从MVC视图保存多个对象

我正在编写我的第一个MVC3应用程序,它是一个简单的订单跟踪应用程序。 我想同时编辑订单和细节。 当我编辑订单时,Edit的ActionResult返回订单和关联的行(我也使用EF)。

public ActionResult Edit(int id) { // Get the order with the order lines var orderWithLines = from o in db.Orders.Include("OrderLines") where o.ID == id select o; // Not sure if this is the best way to do this. // Need to find a way to cast to "Order" type List orderList = orderWithLines.ToList(); Order order = orderList[0]; // Use ViewData rather than passing in the object in the View() method. ViewData.Model = order; return View(); } 

订单和行显示没有问题,但是当我保存页面时,我没有将任何行传递回控制器。 只有订单。 这是View代码。

  @model OrderTracker.Models.Order @{ ViewBag.Title = "Edit"; } 

Edit

@using (Html.BeginForm()) {
Order @Html.HiddenFor(model => model.ID) @Html.HiddenFor(model => model.UserId)
@Html.LabelFor(model => model.OrderDate)
@Html.EditorFor(model => model.OrderDate)
@Html.LabelFor(model => model.Description)
@Html.EditorFor(model => model.Description)
@foreach (var line in Model.OrderLines) { }
Description Quantity Weight Price
@Html.EditorFor(modelItem => line.Description) @Html.EditorFor(modelItem => line.Quantity) @Html.EditorFor(modelItem => line.Weight) @Html.EditorFor(modelItem => line.Price)

}

我能否就保存生产线数据和订单数据的最佳方法获得一些指导。

谢谢。

您遇到的问题与ICollection控件生成的名称有关。 以下是Phil Haack的详细讨论和他的解决方案(就@Html扩展方法而言 ;从他博客文章末尾给出的链接下载示例项目)。 这篇文章的目标是MVC / MVC2; 但它仍然适用于MVC3。

或者,如果您不想遵循hack,则可以为OrderLine实体模型选择EditorTemplate

这是步骤。

1)在( Views ->Shared -> EditorTemplates -> OrderLine.cshtml )下创建编辑器模板在Views ->Shared -> EditorTemplates -> OrderLine.cshtml下创建名为EditorTemplates的文件夹很重要,模板名称应与要为其创建模板的EntityModel相同; 因此命名为OrderLine.cshtml

在此处输入图像描述

2) OrderLine.cshtml的代码

 @model OrderTracker.Models.OrderLine @{ Layout = null; }  @Html.HiddenFor(modelItem => Model.id)   @Html.EditorFor(modelItem => Model.Description)   @Html.EditorFor(modelItem => Model.Quantity)   @Html.EditorFor(modelItem => Model.Weight)   @Html.EditorFor(modelItem => Model.Price)   

3)使用此代码编辑您的视图(请注意我已使用EditorFor for OrderLines集合)

 @model OrderTracker.Models.Order @{ ViewBag.Title = "Edit"; } 

Edit

@using (Html.BeginForm()) {
Order @Html.HiddenFor(model => model.ID) @Html.HiddenFor(model => model.UserId)
@Html.LabelFor(model => model.OrderDate)
@Html.EditorFor(model => model.OrderDate)
@Html.LabelFor(model => model.Description)
@Html.EditorFor(model => model.Description)
@Html.EditorFor(model => model.OrderLines)
Description Quantity Weight Price

}

4)现在回帖后你会看到价值观

在此处输入图像描述

使用MVC它应该是相当直接的,因为框架旨在将表单转换为模型。

 [HttpGet] public ActionResult Edit(int id) { // (you can probably rewrite this using a lambda var orderWithLines = from o in db.Orders.Include("OrderLines") select o; // Use ViewData rather than passing in the object in the View() method. ViewData.Model = orderWithLines.FirstOrDefault(x => x.ID = id); return View(); } [HttpPost] public ActionResult Edit(OrderTracker.Models.Order model) { if (ModelState.IsValid) { // call the service layer / repository / db to persist the object graph _service.Save(model); // this assumes your view models are the same as your domain } } 

问题出在你的foreach上,如果你看一下它生成的原始html,它就不会为每个订单行生成唯一的ID,因此在回发表单时无法绑定模型。

将foreach更改为for循环,然后使用索引引用每个订单行。 这将允许在表单中生成唯一ID,并允许您在回发时将其绑定到模型。

例如

 @for (var counter = 0; counter < Model.OrderLines.Count(); counter++) {   @Html.EditorFor(modelItem => Model.OrderLines[counter].Description)   @Html.EditorFor(modelItem => Model.OrderLines[counter].Quantity)   @Html.EditorFor(modelItem => Model.OrderLines[counter].Weight)   @Html.EditorFor(modelItem => Model.OrderLines[counter].Price)   }