我正在编写我的第一个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<Order> orderList = orderWithLines.ToList();
Order order = orderList[0];
// Use ViewData rather than passing in the object in the View() method.
ViewData.Model = order;
return View();
}
订单和行显示没有问题,但是当我保存页面时,我没有将任何行传递回控制器。只有订单。这是查看代码。
@model OrderTracker.Models.Order
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
<fieldset>
<legend>Order</legend>
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.UserId)
<div>
@Html.LabelFor(model => model.OrderDate)
</div>
<div>
@Html.EditorFor(model => model.OrderDate)
</div>
<div>
@Html.LabelFor(model => model.Description)
</div>
<div>
@Html.EditorFor(model => model.Description)
</div>
<table>
<tr>
<th>
Description
</th>
<th>
Quantity
</th>
<th>
Weight
</th>
<th>
Price
</th>
<th></th>
</tr>
@foreach (var line in Model.OrderLines)
{
<tr>
<td>
@Html.EditorFor(modelItem => line.Description)
</td>
<td>
@Html.EditorFor(modelItem => line.Quantity)
</td>
<td>
@Html.EditorFor(modelItem => line.Weight)
</td>
<td>
@Html.EditorFor(modelItem => line.Price)
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
我能否就保存生产线数据和订单数据的最佳方法获得一些指导。
感谢。
答案 0 :(得分:7)
您遇到的问题与ICollection<T>
控件生成的名称有关。这是一个detailed discussion by Phil Haack和他的解决方案(根据 @Html扩展方法;从他博客文章末尾给出的链接下载示例项目)。这篇文章的目标是MVC / MVC2;但它仍然适用于MVC3。
或者,如果您不想遵循黑客攻击,则可以为EditorTemplate
实体模型选择OrderLine
。
以下是步骤。
1)在(Views ->Shared -> EditorTemplates -> OrderLine.cshtml
)下创建编辑器模板
在EditorTemplates
下创建名为Shared
的文件夹非常重要,模板名称应与要为其创建模板的EntityModel相同;因此名称为OrderLine.cshtml
)
2) OrderLine.cshtml的代码
@model OrderTracker.Models.OrderLine
@{
Layout = null;
}
<!DOCTYPE html>
@Html.HiddenFor(modelItem => Model.id)
<tr>
<td>
@Html.EditorFor(modelItem => Model.Description)
</td>
<td>
@Html.EditorFor(modelItem => Model.Quantity)
</td>
<td>
@Html.EditorFor(modelItem => Model.Weight)
</td>
<td>
@Html.EditorFor(modelItem => Model.Price)
</td>
</tr>
3)使用此代码编辑您的视图(请注意,我已将EditorFor
用于OrderLines集合)
@model OrderTracker.Models.Order
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
<fieldset>
<legend>Order</legend>
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.UserId)
<div>
@Html.LabelFor(model => model.OrderDate)
</div>
<div>
@Html.EditorFor(model => model.OrderDate)
</div>
<div>
@Html.LabelFor(model => model.Description)
</div>
<div>
@Html.EditorFor(model => model.Description)
</div>
<div>
<table>
<tr>
<th>
Description
</th>
<th>
Quantity
</th>
<th>
Weight
</th>
<th>
Price
</th>
</tr>
@Html.EditorFor(model => model.OrderLines)
</table>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
4)现在回帖后你会看到值
答案 1 :(得分:0)
使用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
}
}
答案 2 :(得分:0)
问题在于您的foreach,如果您查看它生成的原始html,它将不会为每个订单行生成唯一的ID,因此在回发表单时将无法绑定模型。< / p>
将foreach更改为for循环,然后使用索引引用每个订单行。这将允许在表单中生成唯一ID,并允许您在回发模型时将其绑定到模型。
e.g。
@for (var counter = 0; counter < Model.OrderLines.Count(); counter++)
{
<tr>
<td>
@Html.EditorFor(modelItem => Model.OrderLines[counter].Description)
</td>
<td>
@Html.EditorFor(modelItem => Model.OrderLines[counter].Quantity)
</td>
<td>
@Html.EditorFor(modelItem => Model.OrderLines[counter].Weight)
</td>
<td>
@Html.EditorFor(modelItem => Model.OrderLines[counter].Price)
</td>
</tr>
}
</table>