我如何将比较属性与父子模型一起使用

时间:2018-09-27 19:16:25

标签: c# asp.net-mvc-4

我有两个用于父级子实体的模型类。每个都有日期属性。

验证规则为:子日期必须小于或等于月份和年份的父日期。 我想使用带有父属性和子属性的compare属性。但是我没有成功将isValid方法的contextValidation参数从父级传递给子级。

请问我如何成功做到这一点?

public class Parent 
{
   public int Id{get; set;}
   public DateTime DateStartParent{get; set;}
   [CompareDate("DateStartParent")]
   public DateTime DateEndParent {get; set;}
   public vertual ICollection<Child> Children{get; set;}
}

public class Child
{
   public int Child{get; set;}
   [CompareChildDate("DateStartParent")]
   public DateTime DateChild {get; set;}
   public virtual Partent Parent{get; set;}
}

namespace BusinessEntities.CustomValidation
{
  public class CompareDate : ValidationAttribute
  {
    public string PropertyToCompar { get; set; }
    public Type ModelType { get; set; }

    public DateCompare(string comparedProperety):base(comparedProperety)
    {
        this.PropertyToCompar = comparedProperety;

    }

    public virtual bool ValidateDate(object value, DateTime comparedValue)
    {

        if (DateTime.Compare(comparedValue, (DateTime)value) < 0)
        {
            this.ErrorMessage = "La Date Début doit etre avant Date Fin";
            return false;
        }

        else
        {
            return true;
        } 

    public bool ValidateMoisEtAnnee(object value, DateTime comparedValue)
    {

        if (comparedValue.Year != ((DateTime)value).Year)
        {
            this.ErrorMessage = "une date de l'année  précédente n'est pas authorisée";
            return false;
        }

        else 
        {
            return comparedValue.Month > ((DateTime)value).Month;
        }


    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //define the entity to validdate
        var dra = (Parent)validationContext.ObjectInstance;
        //define the property to validate with            
        var property = validationContext.ObjectType.GetProperty(this.PropertyToCompar);
        //get the property value
        var comparedValue = (DateTime)property.GetValue(validationContext.ObjectInstance);

        if (!ValidateDate(value, comparedValue))
            return new ValidationResult(this.ErrorMessage);
        else if (dra.DateDebutDra == (DateTime)value && !ValidateMoisEtAnnee(value, comparedValue))
            return new ValidationResult(this.ErrorMessage);
        else if (dra.DateFinDra == (DateTime)value && ValidateMoisEtAnnee(value, comparedValue))
            return new ValidationResult(this.ErrorMessage);
        else
            return ValidationResult.Success;
    }

}



public class DateChildCompare: DateCompare
{
    private string _propertyToCompare;

    public DateDepenseCompare (string propertyToCompare):base(propertyToCompare)
    {
        this._propertyToCompare = propertyToCompare ;   
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //DateTime comparedValue = null;
        //definir the entity to validate with 
        var depense = validationContext.ObjectInstance as Child;
        //definir la proprité ou on applique la validation            
        var property =typeof(Parent).GetProperty(base.PropertyToCompar);
        //get the value of this property

        value = depense.DateDepense;
        return base.IsValid(value, validationContext);                                    

      }

    }
}

1 个答案:

答案 0 :(得分:0)

如果用例相当有限,则可能不需要为子级添加单独的验证属性。遵循以下原则应该可以:

public class Parent
{
  [CompareChildDates]
  public DateTime Time { get; set; }
  public List<Child> Children { get; set; } 
}

public class Child
{
  public DateTime Time { get; set; }
}

public class CompareChildDatesAttribute : ValidationAttribute
{
  protected override ValidationResult IsValid(object value, ValidationContext context)
  {
    if (context.ObjectInstance is Parent parent 
      && value is DateTime parentTime
      && parent.Children.All(child => parentTime >= child.Time))
    {
      return ValidationResult.Success;
    }
    return new ValidationResult("Validation Error Message");
  }
}