单个嵌套对象的MVC服务器端验证

时间:2013-05-14 12:23:08

标签: asp.net asp.net-mvc validation modelstate

我目前正在使用单个操作来处​​理2个视图,这些视图使用单独的ViewModel,如下所示:

[HttpPost]
public ActionResult(PrivateCustomer p, CorporateCustomer c)
{
  if(Modelstate.IsValid) { ... }
}

我的viewmodels看起来像这样:

public abstract class Customer
{
  public string Name {get; set;}
  public string UserName {get; set;}
  ...
}
public class PrivateCustomer: Customer
{
  ...
}
public class CorporateCustomer: Customer
{
  [Required]
  public new string Name {get; set;}
}

这意味着我可以为两个(密切相关的)视图模型使用1个url / action。 但问题是,我接受两个视图模型作为我的后期操作的参数,并且两者都会进行模型验证(即使我只使用一个)。

鉴于我发布了一个不需要姓名的PrivateCustomer,我仍然会在该属性上收到验证错误。

我想知道是否有一种优雅的方式可以防止这种情况发生,最好不要手动从我的ModelState中删除错误。

如果只验证2个对象中的任何一个,那么最好的事情就是。

提前感谢任何建议。

2 个答案:

答案 0 :(得分:0)

由于POST数据在服务器端修改之前已经过检查,因此在模型中很难做到这一点。如果你不想分开你的动作,我建议你在模型中删除[Required]数据注释并在控制器中验证如下:

[HttpPost]
public ActionResult(PrivateCustomer p, CorporateCustomer c)
{

     if (c != null)
     {
          if (c.Name == null || c.Name == "")
          {
               ModelState.AddModelError("Name", "Name is required.");
          }
     }

     if(Modelstate.IsValid) { ... }

}

答案 1 :(得分:0)

您可以通过为要传递给action方法的类型实现自定义ModelBinder来实现此目的。在模型绑定器中,您可以覆盖BindModel。在那里,您可以决定如何构建模型的每个实例,并决定是否包含ModelState错误。由于这是在您输入操作方法之前完成的,因此只有在您的逻辑需要时,您的操作方法才会看到ModelState错误。