Asp.net mvc 验证前需要复制属性

Asp.net mvc 验证前需要复制属性,asp.net-mvc,validation,modelstate,Asp.net Mvc,Validation,Modelstate,我有一个相当复杂的模型需要验证,问题是这个模型在两个不同的地方使用,一个是注册客户,另一个是添加地址。地址上的某些字段在注册客户表单上根本不可见。 因此,当我检查ModelState.IsValid是否有效时,我当然会得到false,因为例如,账单地址上没有输入姓名,但客户上有姓名。这就是为什么我想在进行验证之前,将几个字段复制到模型中,然后进行验证。不过我有点迷路了,我需要帮助 我的行为如下所示: public ActionResult Register(WebCustomer custome

我有一个相当复杂的模型需要验证,问题是这个模型在两个不同的地方使用,一个是注册客户,另一个是添加地址。地址上的某些字段在注册客户表单上根本不可见。 因此,当我检查ModelState.IsValid是否有效时,我当然会得到false,因为例如,账单地址上没有输入姓名,但客户上有姓名。这就是为什么我想在进行验证之前,将几个字段复制到模型中,然后进行验证。不过我有点迷路了,我需要帮助

我的行为如下所示:

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

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

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

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

这个CustomModelBinder应该负责复制字段,因为它应用于动作参数,所以它将只在这个动作中使用。

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

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

此CustomModelBinder应负责复制字段,由于其应用于操作参数,因此将仅在此操作中使用。

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

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

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

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

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

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

我的解决方法有点不同,不确定这是否是最好的方法,但是:

首先,我为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);

我的解决方法有点不同,不确定这是否是最好的方法,但是:

首先,我为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);

但是我该如何检索表单中发布的所有值呢?TryUpdateModel()将尝试将表单中的值放入您的客户对象中(唯一可能出现错误的是,TryUpdateModel将缺少的字段设置为null,结果导致模型验证失败),请尝试一下。是的,就是这样,因为CopyProperties所做的就是使用像Name这样的属性,并将其复制到addresses属性中作为Name,如果Name为null,您可以找出其余的:)好的,所以我正在将我的答案重新输入到更适合这种情况的内容中。但是我如何检索表单中发布的所有值呢?TryUpdateModel()将尝试将表单中的值放入您的客户对象(这里唯一可能出错的是TryUpdateModel将缺少的字段设置为null,结果导致模型验证失败),只需尝试一下就可以了。是的,就是这样,因为CopyProperties所做的就是使用像Name这样的属性,并将其复制到addresses属性中作为Name,如果Name为null,你可以计算出其余的:)好的,那么我将把我的答案重新定义为更适合这种情况的答案?