我正在用MS MVC 3构建一个web应用程序,遇到了一个问题,可能是因为我对模型绑定的理解存在漏洞。
首先,我有一个相当标准的模型(为了简洁起见,省略了无关的内容,更改了名称以保护无辜对象的隐私):
public class ModelBase
{
public int Id { get; set; }
}
public class Order : ModelBase
{
public List<Product> Products { get; set; }
}
public class Product : ModelBase
{
public int OrderId { get; set;}
}
为了显示和编辑这些,我在Order类中有一个强类型的View,其中包含一个在Product类中强类型的Partial View。局部视图的顶部如下所示:
@model Product
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.OrderId)
//loads of actual editable properties
我将部分插入主视图,如下所示:
@Html.Partial("EditorTemplates/Product", Model.Products.First())
当视图在浏览器中呈现时,"Id"隐藏输入包含订单的Id,而不是我期望和需要的产品的Id:(
我错过了什么?是否可以在不更改模型和视图结构的情况下进行修复?
在更改我的测试项目时,我可以确认
/首页/索引?id=33
或
/首页/索引/33
确实覆盖了模型值。你能从url中删除这个参数吗?
您必须更改结构。
您可以将部分内容放在主视图中,或者将部分内容强键入Order而不是Product,或者使用Html.hidden()构造隐藏字段。MVC不会在发布操作中将指向HiddeFor中项目的整个路径相对于模型。
即。在html中,你会看到
<input type="hidden" name="Id" />
但你真的想要
<input type="hidden" name="Products[0].Id" />
以便区分字段和项目。
当您尝试POST两个具有相同名称的不同隐藏输入时,上述问题仍然存在,但是我也编写了一个测试项目,该项目可以在客户端运行。
希望这有帮助:
控制器
public ActionResult Index()
{
Order order = new Order() { Id = 1 };
order.Products = new List<Product>() { new Product() { Id = 3, OrderId = 1 } };
return View("Order",order);
}
型号
public class Order : IdentityBase
{
public List<Product> Products { get; set; }
}
public class Product : IdentityBase
{
public int OrderId { get; set; }
}
public class IdentityBase
{
public int Id { get; set; }
}
查看
@model MvcApplication1.Models.Order
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Order</title>
</head>
<body>
<div>
@Html.HiddenFor(model => model.Id)
@foreach (MvcApplication1.Models.Product product in Model.Products)
{
<div class="product">
@Html.Partial("Product", product)
</div>
}
</div>
</body>
</html>
部分视图
@model MvcApplication1.Models.Product
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.OrderId)
客户端Html
<!DOCTYPE html>
<html>
<head>
<title>Order</title>
</head>
<body>
<div>
<input id="Id" name="Id" type="hidden" value="1" />
<div class="product">
<input id="Id" name="Id" type="hidden" value="3" />
<input id="OrderId" name="OrderId" type="hidden" value="1" />
</div>
</div>
</body>