如何在MVC3中将嵌套的ViewModel从View绑定到Controller?

我正在用C#开发一个ASP.NET MVC 3应用程序,我使用Razor。 我现在正处理一个问题,涉及通过Controller向View传递/接收的ViewModel绑定对象。 让我们说清楚。 我有以下ViewModels:

public class ContainerViewModel { public int ContainerId {get; set;} public string ContainerName {get; set;} public List ItemData {get; set;} } public class ItemPostModel { public int ItemId {get; set;} public string ItemName {get; set;} public int ItemValue {get; set;} } 

ContainerViewModel用于将数据传递给View。 其属性ContainerIdContainerName仅用于显示目的。 必须使用Form填充List属性。 View看起来像这样(它是简化版):

 @Model.ContainerName @using (Html.BeginForm()) { 
@foreach(var item in Model.ItemData) { @Html.TextBox(item.ItemId); @Html.TextBox(item.ItemName); @Html.TextBox(item.ItemValue);

}
}

Controller对应的动作方法如下:

 public ActionResult UpdateItems() { //fill in the ContainerViewModel lcontainer return View("UpdateItems", lcontainer); } [HttpPost] public ActionResult UpdateItems(int containerId, ItemPostModel itemData) { //store itemData into repository } 

问题是,使用此代码,传递给Post ActionMethod UpdateItems的ItemPostModel itemData始终为空。 containerId已正确传递。 如果我在Controller中使用以下代码(显然不是DRY),结果相同;

 [HttpPost] public ActionResult UpdateItems(ContainerViewModel container) { //extract itemData from ContainerViewModel container //store itemData into repository } 

如何“教”我想要存储在List的表单元素的应用程序? 我应该修改ModelBinder还是有一种更简单的方法来执行这个任务? 谢谢大家的回答。

不要在视图中写循环。 使用编辑器模板:

 @Model.ContainerName @using (Html.BeginForm()) { 
@Html.EditorFor(x => x.ItemData)
}

并在相应的编辑器模板内( ~/Views/Shared/EditorTemplates/ItemPostModel.cshtml ):

 @model ItemPostModel @Html.TextBox(x => x.ItemId) @Html.TextBox(x => x.ItemName) @Html.TextBox(x => x.ItemValue) 

在控制器操作中,您可能需要指定前缀:

 [HttpPost] public ActionResult UpdateItems( int containerId, [Bind(Prefix = "ItemData")]ItemPostModel itemData ) { //store itemData into repository } 

这几乎应该是全部。 编辑器模板将负责为绑定生成正确的输入字段名称。