[英]Get the parent object property value in child property in Validation Context
This question is related to Asp.net MVC5. 此问题与Asp.net MVC5有关。 Similar question is answer here : https://stackoverflow.com/questions/7674841/net-mvc3-conditionally-validating-property-which-relies-on-parent-object-proper 类似的问题在这里回答:https://stackoverflow.com/questions/7674841/net-mvc3-conditionally-validating-property-which-relies-on-parent-object-proper
I have the following View Model: 我有以下视图模型:
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 DateOfBirthRange : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return null;
//here validationContext.ObjectInstance is ChildModel
//How do i get the Effective Date of ParentModel?
}
}
ChildModel is a list and I need to validate for DateOfBith of all child models wrt Effective date value in ParentModel. ChildModel是一个列表,我需要验证所有子模型的DateOfBith,并注明ParentModel中的有效日期值。
You need to have a navigation property in your ChildModel class back to its parent. 您需要在ChildModel类中拥有一个导航属性,使其返回其父级。 Then you can do something like the following: 然后,您可以执行以下操作:
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
}
The .NET DataAnnotations based validation does not offer recursive validation. 基于.NET DataAnnotations的验证不提供递归验证。 However, you could extend it as explained here . 但是,您可以按照此处的说明进行扩展。 Doing so, you gain control over how the ValidationContext
(used for validating child objects) is created. 这样,您就可以控制如何创建ValidationContext
(用于验证子对象)。
So, in the ValidateObjectAttribute
of the mentioned article, when instantiating the new ValidationContext
in IsValid
, instead of passing null
as a service provider, you could pass a custom IServiceProvider
that gives you the parent validation context and using its ObjectInstance
you get the parent object being validated. 因此,在上述文章的ValidateObjectAttribute
中,当在IsValid
实例化新的ValidationContext
时,可以通过自定义IServiceProvider
来提供父验证上下文,并使用其ObjectInstance
来传递父对象,而不是将null
作为服务提供者传递已验证。
As an alternative, you could move validation logic to the ParentModel by implementing IValidatableObject
on it. 或者,可以通过在其上实现IValidatableObject
将验证逻辑移至ParentModel。 Arguably, your rule does not apply to the ChildModels themselves, but to the the complete Parent object with all its children, as the effective date is a property of the parent object. 可以说,您的规则不适用于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;
}
}
(assuming a rule for validity of date of birth wrt the effective date, and a name property on ChildModel.) (假设有生效日期和生效日期的规则,以及ChildModel上的name属性。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.