在嵌套对象上调用MVC IValidatableObject

时间:2012-11-12 15:30:23

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

所以我有以下对象

public class Person : IValidatableObject 
{

[Required]
public string Name {get;set;}
[Required]
public string Status {get;set;
public Address Address {get;set;}
 public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {

            if (Status != "Addressless" && Address == null)
            {
                yield return new ValidationResult("An address is required if this person is not addressless");
            }
        }
}

public class Address 
{
[Required]
public string Address1 {get;set;}
[Required]
public string City {get;set;}
}

现在,我的问题是地址值是必需的,因为如果此人确实有地址,则EF Code First不需要地址表中数据库中的空值。这似乎导致了一个问题,因为Person不需要地址,因此如果它们是“无地址”,则不应该进行Address验证,但验证仍然会启动,因为Address需要字段。

有解决方法吗?

2 个答案:

答案 0 :(得分:1)

问题在于Required归属是继承的。因此,即使不需要Address,当您绑定到视图时,也需要地址的各个属性。

最好的办法是为Address创建一个视图模型而不具有任何属性,并将一些验证逻辑放在一个单独的类中,甚至放在验证域逻辑的控制器中。您可以使用ModelState.AddModelError.

添加验证数据

答案 1 :(得分:1)

原因

chris-shouts answerhttps://www.carstensens-tehandel.dk/te-the.html中对类似问题的描述。

  

验证对象时,在Validator.ValidateObject中应用以下过程:

     
      
  1. 验证属性级属性
  2.   
  3. 如果任何验证器无效,则中止验证将返回失败
  4.   
  5. 验证对象级属性
  6.   
  7. 如果任何验证器无效,则中止验证将返回失败
  8.   
  9. 如果在桌面框架上并且该对象实现了IValidatableObject,则调用其Validate方法并返回任何失败
  10.   

您的案例

因此,在您的情况下必需属性验证阻止检查您的IValidationObject。

可能的解决方案

可能的解决办法是在Validate方法

中移动所需的地址检查