需要在验证前复制属性

时间:2010-05-25 08:01:42

标签: asp.net-mvc validation modelstate

我有一个相当复杂的模型需要验证,问题是这个模型用于两个不同的地方,一个是你注册你的客户,另一个是你只是添加地址。地址上的某些字段在注册客户表单中根本不可见。 因此,当我检查ModelState.IsValid时,我当然会因为例如错误而得到假。该名称未在帐单邮寄地址中输入,但在客户上。这就是为什么我想在验证发生之前,将几个字段复制到模型中,然后验证。我有点失落,但我需要帮助。

我的行动看起来像这样:

public ActionResult Register(WebCustomer customer) 
{
     customer.CopyProperties();
     if(TryUpdateModel(customer)) 
     {
       ...
     }
     ...

但它总是返回false,而ModelState.IsValid仍然是false。

3 个答案:

答案 0 :(得分:3)

我认为在这种情况下最好的方法是编写CustomModelBinder,并将其应用到您的动作参数

public ActionResult Register([ModelBinder(typeof(WebCustomerRegisterBinder))]WebCustomer customer)  
{
  if(TryUpdateModel(customer))  
  { 
    ... 
  } 
  ...
}

此CustomModelBinder应该处理复制字段,并且因为它应用于action参数,它将仅用于此操作。

答案 1 :(得分:1)

Binder正在处理表单值。所以,你的ModelState总是抛出一个错误。您必须检查您的实体中的属性,或者第二个选项是编写您自己的模型绑定器。例如

public class Customer
{
    public bool IsValid()
    {
        //TODO: check properties.
    }
}

public ActionResult Register(WebCustomer customer) 
{
    customer.CopyProperties();
    TryUpdateModel(customer);
    if (customer.IsValid())
    {
        ...
    }
    ...

答案 2 :(得分:1)

我有点不同意地解决了它,不确定它是否是最好的方式,但是:

首先,我为ModelStateDictionary做了一个扩展方法

public static void ResetErrors(this ModelStateDictionary modelState)
{
     foreach (var error in modelState.Values.Select(m => m.Errors))
 {
    error.Clear();
 }
}

然后我在行动中做了以下事情:

ModelState.ResetErrors();
customer.CopyProperties();
ValidateModel(customer);