在验证上下文中的子属性中获取父对象属性值

时间:2014-01-23 15:22:02

标签: c# asp.net-mvc validation

此问题与Asp.net MVC5有关。 类似的问题在这里回答: https://stackoverflow.com/questions/7674841/net-mvc3-conditionally-validating-property-which-relies-on-parent-object-proper

我有以下视图模型:

public class ParentModel
{
   public DateTime EffectiveDate {get;set}
   public List<ChildModel> Children {get;set;}
   .....
   .....
}
public class ChildModel
{
   [DateOfBirthRange(ErrorMessage="Date of Birth must be within range")]
   public DateTime DateOfBirth {get;set}
   ......
   ....... 
}

public class DateOfBithRange : ValidationAttribute,IClientValidatable
{
   public override ValidationResult(object value, ValidationContext validationContext)
   {
       //here validationContext.ObjectInstance is ChildModel
       //How do i get the Effective Date of ParentModel?
   }
}

ChildModel是一个列表,我需要验证所有子模型的DateOfBith w.r.t ParentModel中的生效日期值

3 个答案:

答案 0 :(得分:0)

您需要在ChildModel类中将导航属性返回到其父级。然后你可以做类似以下的事情:

public override ValidationResult(object value, ValidationContext validationContext)
{
    var childModel= validationContext.ObjectInstance as ChildModel;
    var effectiveDate  = childModel.Parent.EffectiveDate;
    // do your tests against effectiveDate and childModel date
}

答案 1 :(得分:0)

基于.NET DataAnnotations的验证不提供递归验证。但是,您可以按照here的说明对其进行扩展。这样,您可以控制如何创建ValidationContext(用于验证子对象)。

因此,在上述文章的ValidateObjectAttribute中,在ValidationContext中实例化新的IsValid时,您可以传递一个null作为服务提供商,而不是IServiceProvider。自定义ObjectInstance,它为您提供父验证上下文,并使用其typo3temp/logs/typo3.log来验证父对象。

答案 2 :(得分:0)

作为替代,您可以通过在其上实现IValidatableObject将验证逻辑移至ParentModel。 可以说,您的规则并不适用于ChildModels本身,而是适用于带有其所有子级的完整的Parent对象,因为生效日期是父对象的属性。

public class ParentModel : IValidatableObject
{
    //.....
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var result = new List<ValidationResult>();
        foreach (var child in Children.Where(child => child.DateOfBirth.Date < EffectiveDate.AddYears(-1).Date || child.DateOfBirth.Date > EffectiveDate.Date))
        {
            result.Add(new ValidationResult($"The date of birth {child.DateOfBirth} of child {child.Name} is not between now and a year ago."));
        }

        return result;
    }
}

(假设有生效日期的生效日期规则,以及ChildModel上的name属性。)