ASP.NET MVC - [Bind(Exclude ="Id")的替代方案]

Roo*_*ian 19 c# modelbinders asp.net-mvc-2

是否有[Bind(Exclude = "Id")](相关问题)的替代方案?

我能写一个模型活页夹吗?

Dar*_*rov 32

是的,它有:它被称为视图模型.视图模型是专门针对给定视图的特定需求而定制的类.

所以代替:

public ActionResult Index([Bind(Exclude = "Id")] SomeDomainModel model)
Run Code Online (Sandbox Code Playgroud)

使用:

public ActionResult Index(SomeViewModel viewModel)
Run Code Online (Sandbox Code Playgroud)

其中视图模型仅包含需要绑定的属性.然后,您可以在视图模型和模型之间进行映射.使用AutoMapper可以简化此映射.

作为最佳实践,我建议您始终在视图中使用视图模型.

  • @Darin:所以当你有一个庞大,复杂的域对象图表,其中包含需要在表单上显示的许多属性(以及关系,验证规则等)时,是否重新定义了视图模型中的所有相关属性,手动复制它们之间的所有属性等?这似乎会导致大量重复,硬依赖和冗余代码,所以我一直在避免它像瘟疫 - 即使它看起来像"正确"的方法,在实践中我看不出你会怎么样围绕所有尴尬的重复和重复.. ?? (8认同)
  • +1这是我见过的有关ViewModel与Business模型的最佳描述.从安全的角度来看,我从未想过它.但是**是**使用视图模型的原因,至少对于http. (2认同)
  • @Darin:但您正在复制视图中所需的域模型中的所有属性,对吗?验证注释怎么样,你复制了所有这些注释,或者你只在视图模型上有验证注释吗?(感谢分享!) (2认同)
  • @ mindplay.dk,我只复制我所需的视图。至于验证,我在视图模型上执行验证。我为此使用FluentValidation.NET。不要理会DataAnnotations。 (2认同)

Des*_*ond 13

我想出了一个非常简单的解决方案.

public ActionResult Edit(Person person)
{
    ModelState.Remove("Id"); // This will remove the key 

    if (ModelState.IsValid)
       {
           //Save Changes;
       }
    }
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*ulB 13

您可以使用以下属性直接排除属性;

[BindNever]
Run Code Online (Sandbox Code Playgroud)


Mem*_*sen 7

作为现有答案的补充,C#6可以以更安全的方式排除属性:

public ActionResult Edit(Person person)
{
    ModelState.Remove(nameof(Person.Id));

    if (ModelState.IsValid)
       {
           //Save Changes;
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

要么

public ActionResult Index([Bind(Exclude = nameof(SomeDomainModel.Id))] SomeDomainModel model)
Run Code Online (Sandbox Code Playgroud)