Pil*_*Bob 18 model-binding asp.net-mvc-3
我有一个视图模型发送到我的控制器的编辑操作.ViewModel包含对EntityObjects的引用.(是的,我很喜欢它,并且不需要复制viewmodel中的所有实体属性).
我实例化视图模型,然后调用UpdateModel.我得到一个属性为"null"的错误,这很好,因为它是一个相关的模型.我试图在模型绑定期间排除属性绑定.在调试它时,我在实体中看到模型绑定器试图将属性的值设置为null.
这是我的编辑操作:
var model = new SimplifiedCompanyViewModel(id);
var excludeProperties = new string[] {
"Entity.RetainedEarningsAccount.AccountNo"
,"Property.DiscountEarnedAccount.ExpenseCodeValue"
,"Entity.EntityAlternate.EntityID"
,"Property.BankAccount.BankAccountID"
,"Entity.PLSummaryAccount.AccountNo"
,"Property.RefundBank.BankAccountID"
,"Company.Transmitter.TCC"
};
try
{
UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);
if (ModelState.IsValid)
{
//db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
我已经看了一些关于指定"前缀"的其他问题,但我不认为这是问题,因为我告诉它绑定到viewmodel实例而不仅仅是实体对象.
我是否正确排除了这些属性?奇怪的是,这件事似乎只发生了.我怀疑这可能是一个问题,实际上没有与我的实体相关的退款银行.但我有其他相关的项目不存在,并没有看到相同的问题.
更多信息...因为我告诉我模型设计不好.
本公司与BankAccount有关.公司视图显示当前相关的BankAccount.BankAccountId,并且BankAccount.Key有一个隐藏字段.我使用jQueryUI自动完成功能提供显示BankAccount.BankAccountId的银行帐户下拉列表,当选择一个时,jQuery代码会更改隐藏字段以获得正确的Key值.因此,当发布此消息时,我不希望修改当前的银行账户BankAccountID,因此我希望它跳过绑定该字段.
如果我在模型中排除BankAccountId,那么在BankAccount编辑视图中,用户永远无法更改BankAccountId,因为它不会被绑定.我不确定这表明模型设计不佳.
Dis*_*ile 54
[Bind(Exclude="Id,SomeOtherProperty")]
public class SimplifiedCompanyViewModel
{
public int Id { get; set; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
这是System.Web.Mvc命名空间的一部分.它需要以逗号分隔的属性名列表,以便在绑定时排除.
您还应该考虑使用TryUpdateModel而不是UpdateModel.您也可以通过将其作为参数传递给构造函数来使其默认模型绑定器:
public ActionResult Create([Bind(Exclude="Id")]SimplifiedCompanyViewModel model)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我想出了一个非常简单的解决方案.
try
{
UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);
ModelState.Remove("Entity.RetainedEarningsAccount.AccountNo");
ModelState.Remove("Property.DiscountEarnedAccount.ExpenseCodeValue");
ModelState.Remove("Entity.EntityAlternate.EntityID");
ModelState.Remove("Property.BankAccount.BankAccountID");
ModelState.Remove("Entity.PLSummaryAccount.AccountNo");
ModelState.Remove("Property.RefundBank.BankAccountID");
ModelState.Remove("ompany.Transmitter.TCC");
if (ModelState.IsValid)
{
//db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
这里的另一个选择是不要在您的视图中包含此属性,并且它不会被绑定。是的 - 如果有人在页面上创建模型注入,您仍然愿意接受模型注入,但这是另一种选择。MVC 中的默认模板会将 EditorFor 等创建为单独的项目,因此您可以删除它们。这会阻止您将单行视图编辑器与 EditorForModel 一起使用,但模板无论如何都不会以这种方式生成它。
编辑(添加上面的评论)
DRY 通常适用于逻辑,而不适用于视图模型。一种视图=一种视图模型。使用自动映射器可以轻松地在它们之间进行映射。Jimmy Bogard 对此有一个很棒的属性,使其几乎是自动的 - 即,您创建视图模型,加载您的 Customer 实体,然后在操作方法中返回它。然后,AutpMap 属性会将其转换为 ViewModel。请参阅losechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models
| 归档时间: |
|
| 查看次数: |
35133 次 |
| 最近记录: |