ViewModel的列表在操作中为空

时间:2011-08-23 02:39:23

标签: asp.net asp.net-mvc asp.net-mvc-3

我正在开发我的第一个ASP.NET MVC 3应用程序,我有一个看起来像这样的视图:

@model IceCream.ViewModels.Note.NotesViewModel
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    @Html.TextBoxFor(m => m.Name)

    foreach (var item in Model.Notes)
    {
        @Html.EditorFor(m => item);
    }

    <input type="submit" value="Submit"/>
}

我有一个看起来像这样的EditorTemplate:

@model IceCream.ViewModels.Note.NoteViewModel
<div>
    @Html.HiddenFor(m => m.NoteID)
    @Html.TextBoxFor(m => m.NoteText)
    @Html.CheckBoxFor(m => m.IsChecked)
</div>

NotesViewModel看起来像这样:

    public class NotesViewModel
    {
        public string Name { get; set; }
        public IEnumerable<NoteViewModel> Notes { get; set; }
    }

NoteViewModel如下所示:

public class NoteViewModel
{
    public int NoteID { get; set; }
    public System.DateTime Timestamp { get; set; }
    public string NoteText { get; set; }
    public bool IsChecked { get; set; }
}

NotesViewModel在传递给视图时填充得很好。但是,单击提交按钮时,处理帖子的控制器操作仅具有viewmodel的Name属性的值。 Notes属性 - 用户已选中/取消选中的注释列表 - 为空。在显示视图和发回ViewModel时,我在填充TextBoxFor和CheckBoxFor元素之间断开连接。对此的指导?


感谢Mystere Man让我直截了当。据我所知,主要是通过将我的循环改为

@Html.EditorFor(m => m.Notes)

更改底层HTML,我理解为该帖子提供了正确的模型绑定。查看生成的HTML,我看到我为其中一个Notes生成了以下内容:

<div>
  <input id="Notes_0__NoteId" type="hidden" value="1" name="Notes[0].NoteId">
  <input id="Notes_0__NoteText" type="text" value="Texture of dessert was good." name="Notes[0].NoteText">
  <input id="Notes_0__IsChecked" type="checkbox" value="true" name="Notes[0].IsChecked>
</div>

与我原始代码生成的HTML不同:

<div>
   <input id="item_NoteId" type="hidden" value="1" name="item.NoteId>
   <input id="item_NoteText" type="text" value="Texture of dessert was good." name="item.NoteText" >
   <input id="item_IsChecked" type="checkbox" value="true" name="item.IsChecked">
</div>

通过循环遍历Notes,生成的HTML实际上丢失了对viewmodel的Notes属性的任何引用,并且在HTML被正确填充时,复选框值的设置无法将它们的值传递回viewmodel,我猜是模型绑定的重点。

所以我学到了一些东西,这很好。

2 个答案:

答案 0 :(得分:15)

你是一个聪明人,所以看看你的观点。然后,考虑如何生成HTML。然后,考虑模型Binder如何根据生成的HTML重新填充Notes的回发。

我认为你会发现你的HTML中没有足够的信息让Model Binder搞清楚。

考虑一下:

@EditorFor(m => Model.Notes)

而不是for循环,你基本上是从EditorFor函数隐藏上下文。

答案 1 :(得分:3)

对于那些只想把答案作为for循环的人来说:

@for (int x = 0; x < Model.Notes.Count(); x++) {
    @Html.HiddenFor(m => m.Notes[x].NoteId)
    @Html.EditorFor(m => m.Notes[x].NoteText)
    @Html.EditorFor(m => m.Notes[x].IsChecked)
}