如何在 MVC3 中将嵌套的 ViewModel 从视图绑定到控制器?
我正在使用 C# 开发 ASP.NET MVC 3 应用程序,并使用 Razor。我现在正在处理一个有关通过控制器向视图传递/从视图接收的视图模型绑定对象的问题。 让我们说清楚。我有以下 ViewModel:
public class ContainerViewModel
{
public int ContainerId {get; set;}
public string ContainerName {get; set;}
public List<ItemPostModel> ItemData {get; set;}
}
public class ItemPostModel
{
public int ItemId {get; set;}
public string ItemName {get; set;}
public int ItemValue {get; set;}
}
ContainerViewModel 用于将数据传递到视图。其属性 ContainerId 和 ContainerName 仅用于显示目的。必须使用 Form 填写 List
属性。视图看起来像这样(它是一个简化版本):
<strong>@Model.ContainerName</strong>
@using (Html.BeginForm())
{
<fieldset>
@foreach(var item in Model.ItemData)
{
@Html.TextBox(item.ItemId);
@Html.TextBox(item.ItemName);
@Html.TextBox(item.ItemValue);
<p>
<input type="submit" value="Save" />
</p>
}
</fieldset>
}
Controller 相应的 action 方法 如下:
public ActionResult UpdateItems()
{
//fill in the ContainerViewModel lcontainer
return View("UpdateItems", lcontainer);
}
[HttpPost]
public ActionResult UpdateItems(int containerId, ItemPostModel itemData)
{
//store itemData into repository
}
问题在于,使用此代码时 ItemPostModel itemData传递给 Post ActionMethod UpdateItems 的始终为空。 containerId 已正确传递。如果我在控制器中使用以下代码,结果相同(显然不是 DRY);
[HttpPost]
public ActionResult UpdateItems(ContainerViewModel container)
{
//extract itemData from ContainerViewModel container
//store itemData into repository
}
我如何“教导”应用程序我希望将表单元素存储在List
中?我应该修改 ModelBinder 还是有更简单的方法来执行此任务?谢谢大家的回答。
I am developing an ASP.NET MVC 3 application in C# and I use Razor. I am now dealing with a problem concerning the binding of objects through ViewModels passed/received to/from the View by the Controller.
Let's make it clear. I have the following ViewModels:
public class ContainerViewModel
{
public int ContainerId {get; set;}
public string ContainerName {get; set;}
public List<ItemPostModel> ItemData {get; set;}
}
public class ItemPostModel
{
public int ItemId {get; set;}
public string ItemName {get; set;}
public int ItemValue {get; set;}
}
The ContainerViewModel is used to pass the data to the View. Its properties ContainerId and ContainerName are used just for display purposes. The List<ItemPostModel>
property has to be filled using a Form. The View looks something like this (it is a simplified version):
<strong>@Model.ContainerName</strong>
@using (Html.BeginForm())
{
<fieldset>
@foreach(var item in Model.ItemData)
{
@Html.TextBox(item.ItemId);
@Html.TextBox(item.ItemName);
@Html.TextBox(item.ItemValue);
<p>
<input type="submit" value="Save" />
</p>
}
</fieldset>
}
The Controller corresponding action methods are as follows:
public ActionResult UpdateItems()
{
//fill in the ContainerViewModel lcontainer
return View("UpdateItems", lcontainer);
}
[HttpPost]
public ActionResult UpdateItems(int containerId, ItemPostModel itemData)
{
//store itemData into repository
}
The problem is that with this code the ItemPostModel itemData passed to the Post ActionMethod UpdateItems is always empty. The containerId is correctly passed. Same result if I use the following code in the Controller (obviously not DRY);
[HttpPost]
public ActionResult UpdateItems(ContainerViewModel container)
{
//extract itemData from ContainerViewModel container
//store itemData into repository
}
How can I "teach" the application that I want the form elements stored in the List<ItemPostModel>
? Shall I modify the ModelBinder or there is a simpler way to perform this task? Thanks everybody for your answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要在视图中编写循环。使用编辑器模板:
并在相应的编辑器模板(
~/Views/Shared/EditorTemplates/ItemPostModel.cshtml
)内:并且在控制器操作中,您可能需要指定前缀:
这应该差不多了全部。编辑器模板将负责生成正确的输入字段名称以使绑定正常工作。
Don't write loops in a view. Use editor templates:
and inside the corresponding editor template (
~/Views/Shared/EditorTemplates/ItemPostModel.cshtml
):And in the controller action you might need to specify the prefix:
and that should be pretty much all. The editor template will take care of generating the proper input field names for the binding to work.