3

我正在用MS MVC 3構建一個web應用程序,並且遇到了一個問題,可能是由於我對模型綁定的理解有一個漏洞。ASP.Net MVC強類型部分視圖和繼承屬性

首先,我有一個相當標準模型(略去了無關的東西,名稱變更爲保護無辜對象的隱私):

public class ModelBase 
{ 
    public int Id { get; set; } 
} 

public class Order : ModelBase 
{ 
    public List<Product> Products { get; set; } 
} 

public class Product : ModelBase 
{ 
    public int OrderId { get; set;} 
} 

顯示和編輯這些,我有一個看法強類型來Order類包含強類型爲Product類的Partial View。局部視圖的頂部看起來是這樣的:

@model Product 

@Html.ValidationSummary(true) 
@Html.HiddenFor(model => model.Id) 
@Html.HiddenFor(model => model.OrderId) 
//loads of actual editable properties 

我插入部分成這樣的主要觀點:

@Html.Partial("EditorTemplates/Product", Model.Products.First()) 

...當視圖在瀏覽器中呈現的「 ID爲」隱藏輸入包含訂單的ID,產品的不是ID,我期待和需要:(

我缺少什麼?它可以是固定不改變模型和視圖的結構?

+0

看起來不錯,你怎麼知道Id是訂單? OrderId是否正確顯示? – Wil 2012-01-30 13:40:00

+1

OrderId確實顯示正確,並且它與Id字段中顯示的值相同。我想我不確定它是來自Order的值,因爲該值也作爲請求url的一部分存在(/ Orders/Step2/10,其中10是Order Id)。它可能是覆蓋Id字段的這個值嗎? – Atrieos 2012-01-31 08:33:49

+0

您可以通過數據庫確認orderid是否與此記錄的id相同? – Wil 2012-01-31 09:52:24

回答

3

在改變我的測試項目中,我可以證實,

/首頁/指數?ID = 33

/Home/Index/33

是否覆蓋模型值。你可以從url中刪除這個參數嗎?

+2

就是這樣!活頁夾將路由值放入字段中,以不區分大小寫的方式並覆蓋模型中的值。我在Global.Asax中爲應用程序的Order-editing部分添加了一條新路線,如下所示: ''Orders/{StepNo}/{OrderId}「'...現在我的值被保留了,因爲它不再匹配默認routevalue {id}到我的「Id」字段。它所需要的只是我的行動參數的新路線和一些新名字。沒有必要進行結構性改變,MVC也沒有像我第一次擔心的繼承問題。感謝一幫幫忙:) – Atrieos 2012-01-31 14:00:43

1

你必須改變結構。

您可以將部分內容放入主視圖中,也可以使用Html.Hidden()構造隱藏字段。 MVC並沒有將整個路徑放置在相對於您的發佈操作中的模型的HiddenFor中。

即。在HTML中,你會看到

<input type="hidden" name="Id" /> 

但真要

<input type="hidden" name="Products[0].Id" /> 

爲了區分領域和項目。


上述問題,當你試圖用同樣的名義發佈兩個不同的隱藏輸入仍然存在,但是,我也寫了一個測試項目,只要客戶端運行。

希望這有助於:

控制器

public ActionResult Index() 
     { 
      Order order = new Order() { Id = 1 }; 
      order.Products = new List<Product>() { new Product() { Id = 3, OrderId = 1 } }; 
      return View("Order",order); 
     } 

模型

public class Order : IdentityBase 
    { 
     public List<Product> Products { get; set; } 
    } 

    public class Product : IdentityBase 
    { 
     public int OrderId { get; set; } 
    } 

public class IdentityBase 
    { 
     public int Id { get; set; } 
    } 

查看

@model MvcApplication1.Models.Order 

@{ 
    Layout = null; 
} 

<!DOCTYPE html> 

<html> 
<head> 
    <title>Order</title> 
</head> 
<body> 
    <div> 
     @Html.HiddenFor(model => model.Id) 
     @foreach (MvcApplication1.Models.Product product in Model.Products) 
     { 
      <div class="product"> 
       @Html.Partial("Product", product) 
      </div> 
     } 
    </div> 
</body> 
</html> 

管窺

@model MvcApplication1.Models.Product 

@Html.ValidationSummary(true) 
@Html.HiddenFor(model => model.Id) 
@Html.HiddenFor(model => model.OrderId) 

客戶端HTML

<!DOCTYPE html> 
<html> 
<head>  
    <title>Order</title>  
</head>  
<body>  
    <div>  
     <input id="Id" name="Id" type="hidden" value="1" />  
     <div class="product"> 
       <input id="Id" name="Id" type="hidden" value="3" />  
       <input id="OrderId" name="OrderId" type="hidden" value="1" />  
     </div> 
    </div> 
</body> 

+0

以下是我們獲得此見解的地方: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx – Kaido 2012-01-30 14:23:18

+0

我明白如何爲集合構建控件,但這不是我想做。這只是我試圖編輯的第一個元素。正如您可以從部分路徑中看出的一樣,我期待在整個應用程序中重新使用部分產品編輯。 嘗試使用'@ Html.Hidden(「Id」,Model.Id)'產生與HiddenFor相同的(錯誤的)結果。然而,執行@ Html.Hidden(「P_Id」,Model.Id)會給出預期的值,然而,顯然正確的值存在於局部視圖中,但只是在某個點被覆蓋。 – Atrieos 2012-01-31 08:37:53

+0

你的Html表單的範圍是什麼?是否有可能發回兩個名稱爲「Id」的元素?您可以在頁面的html中或POST動作中的表單值集合中檢查此項。 – Kaido 2012-01-31 10:43:43