2011-07-05 58 views
30

我有一個基本的ViewModel屬性是一個複雜類型的列表。綁定時,我似乎一直在獲取值列表或其他模型屬性,取決於發佈的值(即視圖排列)。MVC綁定到模型與列表屬性忽略其他屬性

視圖模型:

public class MyViewModel 
{ 
    public int Id { get; set; } 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 

    public List<MyDataItem> Data { get; set; } 
} 

public class MyDataItem 
{ 
    public int Id { get; set; } 
    public int ParentId { get; set; } 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

控制器操作:

public ActionResult MyForm() 
    { 
     MyViewModel model = new MyViewModel(); 

     model.Id = 1; 
     model.Data = new List<MyDataItem>() 
     { 
      new MyDataItem{ Id = 1, ParentId = 1, Name = "MyListItem1", Value = "SomeValue"} 
     }; 

     return View(model); 
    } 

    [HttpPost] 
    public ActionResult MyForm(MyViewModel model) 
    { 
     //... 

     return View(model); 
    } 

下面是基本視圖(無單加價)

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>My View Model</legend> 

     @Html.HiddenFor(model => model.Id) 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Property1) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Property1) 
      @Html.ValidationMessageFor(model => model.Property1) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Property2) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Property2) 
      @Html.ValidationMessageFor(model => model.Property2) 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

當調回控制器,我得到2個屬性值和'數據'屬性的空值如預期。

Without List Mark-up

如果我添加了加價的名單如下(基於此Scott Hanselman postPhil Haack's post的信息):

<div class="editor-field"> 
@for (int i = 0; i < Model.Data.Count(); i++) 
{ 
    MyDataItem data = Model.Data[i]; 
    @Html.Hidden("model.Data[" + i + "].Id", data.Id) 
    @Html.Hidden("model.Data[" + i + "].ParentId", data.ParentId) 
    @Html.Hidden("model.Data[" + i + "].Name", data.Name) 
    @Html.TextBox("model.Data[" + i + "].Value", data.Value) 
} 
</div> 

模型的「數據」屬性是成功綁定但其他屬性爲空。

With List Mark-up

貼在表格值如下:

Id=1&Property1=test1&Property2=test2&model.Data%5B0%5D.Id=1&model.Data%5B0%5D.ParentId=1&model.Data%5B0%5D.Name=MyListItem1&model.Data%5B0%5D.Value=SomeValue 

有沒有辦法讓這兩套填充性能還是我只是缺少明顯的東西?

編輯:

對於那些你們誰是好奇。基於從MartinHN了答案,原來產生的加價爲:

<div class="editor-field"> 
    <input id="model_Data_0__Id" name="model.Data[0].Id" type="hidden" value="1" /> 
    <input id="model_Data_0__ParentId" name="model.Data[0].ParentId" type="hidden" value="1" /> 
    <input id="model_Data_0__Name" name="model.Data[0].Name" type="hidden" value="MyListItem1" /> 
    <input id="model_Data_0__Value" name="model.Data[0].Value" type="text" value="SomeValue" />   
</div> 

新產生的加價是:

<div class="editor-field"> 
    <input id="Data_0__Id" data-val="true" name="Data[0].Id" type="hidden" value="1" data-val-number="The field Id must be a number." data-val-required="The Id field is required." /> 
    <input id="Data_0__ParentId" name="Data[0].ParentId" type="hidden" value="1" data-val="true" data-val-number="The field ParentId must be a number." data-val-required="The ParentId field is required." /> 
    <input id="Data_0__Name" name="Data[0].Name" type="hidden" value="MyListItem1" /> 
    <input id="Data_0__Value" name="Data[0].Value" type="text" value="SomeValue" />   
</div> 

導致以下貼出值:

Id=1&Property1=test1&Property2=test2&Data%5B0%5D.Id=1&Data%5B0%5D.ParentId=1&Data%5B0%5D.Name=MyListItem1&Data%5B0%5D.Value=SomeValue 

注意,沒有「模型」。在名稱和發佈的價值觀......

+0

不要高傑克的胎面或任何東西..但如何將更新現有的公開列表數據{get;組; } - 添加一個項目,減去等,然後更新客戶端上的父模型,而不刷新屏幕?如果數據爲空,並且只能在運行時基於用戶對父模型的其他屬性的選擇纔可以知道?那麼,我想這是一個高傑克希望我們在同一方向:) – user748954

回答

33

嘗試改變的數據收集到這個代碼,並讓MVC照顧的命名:

<div class="editor-field"> 
@for (int i = 0; i < Model.Data.Count(); i++) 
{ 
    @Html.HiddenFor(m => m.Data[i].Id) 
    @Html.HiddenFor(m => m.Data[i].ParentId) 
    @Html.HiddenFor(m => m.Data[i].Name) 
    @Html.TextBoxFor(m => m.Data[i].Value) 
} 
</div> 
+2

我真的不能相信我錯過了。謝謝您的幫助! – robmzd

+1

沒問題!很高興它解決了。 – MartinHN

11

或者你可以爲創建EditorTemplate您如下嵌套ViewModel。

@model MyDataItem 
@Html.HiddenFor(model => model.Id) 
@Html.HiddenFor(model => model.ParentId) 
@Html.HiddenFor(model => model.Name) 
@Html.TextBoxFor(model => model.Value) 

創建一個在你的「共享」文件夾命名爲「EditorTemplates」文件夾並保存上述爲「MyDataItem.cshtml」。

然後在您的視圖,只需調用下面,而不是foreach循環:

@Html.EditorFor(model => model.Data) 

感覺少了幾分hackier IMO :)

4

只是我的2美分,但有些東西值得這個問題提 - 視圖模型中的數據成員必須定義爲回發模型綁定起作用的公共屬性。 我有一個非常類似的問題,但在我的視圖模型中使用公共數據成員。如上所示生成相同的HTML,並且所有外觀都很好,但模型聯編程序回退了一個空集合。值得關注...