Asp.net mvc 3 调用UpdateModel()时,如何从绑定中排除属性?

Asp.net mvc 3 调用UpdateModel()时,如何从绑定中排除属性?,asp.net-mvc-3,model-binding,Asp.net Mvc 3,Model Binding,我已将视图模型发送到控制器的编辑操作。ViewModel包含对EntityObjects的引用。(是的,我可以接受,不需要复制viewmodel中的所有实体属性) 我实例化视图模型,然后调用UpdateModel。我得到一个错误,即属性为“null”,这很好,因为它是一个相关模型。我试图在模型绑定期间排除绑定属性。调试时,我在实体中看到模型绑定器试图将属性值设置为null 以下是我的编辑操作: var model = new SimplifiedCompanyViewModel(id); va

我已将视图模型发送到控制器的编辑操作。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);
}
var模型=新的简化公司视图模型(id);
var excludeProperties=新字符串[]{
“Entity.RetaineDearingsAccount.AccountNo”
,“属性.折扣学习帐户.支出代码值”
,“Entity.EntityAlternate.EntityID”
,“Property.BankAccount.BankAccountID”
,“Entity.PLSummaryAccount.AccountNo”
,“Property.ReturnBank.BankAccountID”
,“公司变送器TCC”
};
尝试
{
UpdateModel(model,String.Empty,null,excludeProperties);
if(ModelState.IsValid)
{
//db.SaveChanges();
}
返回操作(“索引”);
}
抓住
{
返回视图(模型);
}
我已经研究了一些关于指定“前缀”的其他问题,但我认为这不是问题所在,因为我告诉它绑定到viewmodel实例,而不仅仅是实体对象

我是否正确排除了这些属性?奇怪的事情似乎只发生在这个项目上。我怀疑这可能是一个问题,因为我的实体实际上没有退款银行。但我有其他相关的项目,不存在,也没有看到相同的问题

更多信息。。。因为有人告诉我模型设计得不好

该公司与一个银行账户有关联。“公司”视图显示当前相关的BankAccount.BankAccountId,并且有一个隐藏字段,其中包含BankAccount.Key。我使用jQueryUI自动完成功能提供一个银行帐户下拉列表,显示BankAccount.BankAccountId,当选择其中一个时,jQuery代码更改隐藏字段以获得正确的键值。因此,当发布此信息时,我不希望修改当前的bankaccounts BankAccountID,因此我希望它跳过绑定该字段

如果我在模型中排除BankAccountId,那么在BankAccount编辑视图中,用户将永远无法更改BankAccountId,因为它不会被绑定。我不确定这如何表明模型设计不佳。

请尝试该属性。
我承认我从未用过它

[Exclude]
public Entity Name {get; set;}
使用属性的属性:

[Bind(Exclude="Id,SomeOtherProperty")]
public class SimplifiedCompanyViewModel
{
    public int Id { get; set; }

    // ...
}
这是
System.Web.Mvc
命名空间的一部分。绑定时要排除的属性名称列表以逗号分隔

你也应该考虑使用TyuPuffDimoDell而不是UpdateModel。您也可以让默认模型绑定器将其作为参数传递给构造函数,从而解决该问题:

public ActionResult Create([Bind(Exclude="Id")]SimplifiedCompanyViewModel model)
{
    // ...
}

这里的另一个选项就是不要在视图中包含这个属性,它不会被绑定。是-如果有人在页面上创建模型注入,那么您仍然可以进行模型注入,但这是另一种选择。MVC中的默认模板将创建EditorFor等作为单独的项,以便您可以删除它们。这会阻止您将单线视图编辑器与EditorForModel一起使用,但模板不会以这种方式为您生成它

编辑(添加上述注释)


DRY通常适用于逻辑,而不是视图模型。一个视图=一个视图模型。使用automapper可以轻松地在它们之间进行映射。Jimmy Bogard对此有一个很好的属性,这使得它几乎是自动的-即创建视图模型,例如加载客户实体,然后在action方法中返回它。然后,AutpMap属性将其转换为ViewModel。请参阅我想出的一个非常简单的解决方案

 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);
}
试试看
{
UpdateModel(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.returnBank.BankAccountID”);
ModelState.Remove(“ompany.transmitor.TCC”);
if(ModelState.IsValid)
{
//db.SaveChanges();
}
返回操作(“索引”);
}
抓住
{
返回视图(模型);
}

您可能对它很满意,但在未来的道路上,您将面临潜在的麻烦。如果向实体中添加了新的值,而您没有考虑这些值。假设您添加了一个名为“Discentrate”(假设)的字段,最终用户看到它在其他地方使用,他们可以将该值包含在表单中并注入您的模型。使用ViewModels还有很多其他原因。复制属性通常是一个简单的复制/粘贴/清理,它不适用于这里的干燥原则。好吧,你一针见血。对我来说,这似乎不是很枯燥。枯燥通常适用于逻辑,而不是查看模型。一个视图=一个视图模型。使用automapper可以轻松地在它们之间进行映射。Jimmy Bogard对此有一个很好的属性,这使得它几乎是自动的-即创建视图模型,例如加载客户实体,然后在action方法中返回它。然后,AutpMap属性将其转换为ViewModel。查看ViewModel是否与模型相同,我觉得它不干燥。然而,这是一个如此复杂的视图,它使用了几个相关的实体,我可能不得不求助于这样做。我只是不确定automapper或其他东西处理所有关系的效果如何,我可能需要手动编写所有更新代码。我来看看你上面列出的文章。是的,如果是手册,那么你就不必担心bankaccount.name会被绑定回去。嗯。。我不想我