我有一个相当复杂的模型需要验证,问题是这个模型用于两个不同的地方,一个是你注册你的客户,另一个是你只是添加地址。地址上的某些字段在注册客户表单中根本不可见。 因此,当我检查ModelState.IsValid时,我当然会因为例如错误而得到假。该名称未在帐单邮寄地址中输入,但在客户上。这就是为什么我想在验证发生之前,将几个字段复制到模型中,然后验证。我有点失落,但我需要帮助。
我的行动看起来像这样:
public ActionResult Register(WebCustomer customer)
{
customer.CopyProperties();
if(TryUpdateModel(customer))
{
...
}
...
但它总是返回false,而ModelState.IsValid仍然是false。
答案 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);