ASP.NET MVC5 Model Binder - 绑定集合集合时为空

ASP.NET MVC5 Model Binder - Null when binding collection of collections

我已经在网上进行了研究,但希望有人能帮助我。

我有以下 ViewModel 类:

public class PersonEditViewModel
{
    public Person Person { get; set; }
    public List<DictionaryRootViewModel> Interests { get; set; }
}

public class DictionaryRootViewModel
{
    public long Id { get; set; }
    public string Name { get; set; }
    public ICollection<DictionaryItemViewModel> Items;

    public DictionaryRootViewModel()
    {
        Items = new List<DictionaryItemViewModel>();
    }
}

public class DictionaryItemViewModel
{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool Selected { get; set; }
}

在“编辑”视图中,我使用自定义 EditorTemplate 来使用 @Html.EditorFor(m => m.Interests) 对兴趣集合进行布局。有两个 EditorTemplates 做渲染:

  1. DictionaryRootViewModel.cshtml:

    @model Platforma.Models.DictionaryRootViewModel
    @Html.HiddenFor(model => model.Id)
    @Html.HiddenFor(model => model.Name)
    @Html.EditorFor(model => model.Items)
    
  2. DictionaryItemViewModel.cshtml:

    @model Platforma.Models.DictionaryItemViewModel
    @Html.HiddenFor(model => model.Id)
    @Html.CheckBoxFor(model => model.Selected)
    @Html.EditorFor(model => model.Name)
    

问题:

使用 POST 提交表单时,只会填充 Interests 集合,而 Interest.Items 集合始终为空。 该请求包含(除其他外)以下字段名称,它们在控制器操作方法中检查 Request.Forms 数据时也存在。

所有都包含正确的值 - 但在控制器端,方法中的对象 pvm:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(PersonEditViewModel pvm)
{
}

包含 Interests 集合中的数据(具有正确 ID 和名称的项目),但对于该集合的每个元素,它的 Items 子集合都是空的。

如何才能正确选择模型?

大多数时候问题出在索引上,当你有 collections 发布时,你要么需要有顺序索引,要么有 Interests[i].Items.Index 隐藏字段(如果索引不是顺序的) .

Here is similar question on SO

如果你有

,它将不会工作
Interests[0].Id
Interests[0].Name
Interests[0].Items[0].Id
Interests[0].Items[0].Selected
Interests[0].Items[2].Id
Interests[0].Items[2].Selected

所以要修复它,您要么确保有顺序索引

Interests[0].Id
Interests[0].Name
Interests[0].Items[0].Id
Interests[0].Items[0].Selected
Interests[0].Items[1].Id
Interests[0].Items[1].Selected

Interests[0].Id
Interests[0].Name
Interests[0].Items.Index = 0 (hidden field)
Interests[0].Items[0].Id
Interests[0].Items[0].Selected
Interests[0].Items.Index = 2 (hidden field)
Interests[0].Items[2].Id
Interests[0].Items[2].Selected

像往常一样 - 答案一直在我面前。 DefaultModelBinder 没有获取请求中传递的 Items 值,因为我 "forgot" 将 Items 集合标记为 属性 - 它是一个字段! 考虑到@pjobs 的有用评论的正确形式:

public List<DictionaryItemViewModel> Items{获取;设置;}