Подтвердить что ты не робот

Аннотации данных mvc4 сравнивают две даты

У меня есть эти два поля в моей модели:

[Required(ErrorMessage="The start date is required")]
[Display(Name="Start Date")]
[DisplayFormat(DataFormatString = "{0,d}")]
public DateTime startDate { get; set; }

[Required(ErrorMessage="The end date is required")]
[Display(Name="End Date")]
[DisplayFormat(DataFormatString = "{0,d}")]
public DateTime endDate{ get; set; }

Я требую, чтобы endDate был больше, чем startDate. Я попытался использовать [Compare("startDate")], но это работает только для равных операций.

Что я должен использовать для операции "больше"?

4b9b3361

Ответ 1

Взгляните на Свободная проверка или Проверка надежности MVC: это может помочь вам.

С Foolproof, например, есть аннотация [GreaterThan("StartDate")], которую вы можете использовать в свойстве даты.

Или, если вы не хотите использовать другие библиотеки, вы можете реализовать свою собственную проверку, реализовав IValidatableObject в своей модели:

public class ViewModel: IValidatableObject
{
    [Required]
    public DateTime StartDate { get; set; }
    [Required]    
    public DateTime EndDate { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
       if (EndDate < StartDate)
       {
           yield return 
             new ValidationResult(errorMessage: "EndDate must be greater than StartDate",
                                  memberNames: new[] { "EndDate" });
       }
    }
}

Ответ 2

Интерфейс IValidatableObject обеспечивает способ проверки объекта, который реализует метод IValidatableObject.Validate(ValidationContext validationContext). Этот метод всегда возвращает объект IEnumerable. Для этого вам необходимо создать список объектов и ошибок ValidationResult и вернуть их. Пустой список означает подтверждение ваших условий. Это выглядит следующим образом в mvc 4...

 public class LibProject : IValidatableObject
{
    [Required(ErrorMessage="Project name required")]

    public string Project_name { get; set; }
    [Required(ErrorMessage = "Job no required")]
    public string Job_no { get; set; }
    public string Client { get; set; }
    [DataType(DataType.Date,ErrorMessage="Invalid Date")]
    public DateTime ExpireDate { get; set; }


    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        List < ValidationResult >  res =new List<ValidationResult>();
        if (ExpireDate < DateTime.Today)
        {
            ValidationResult mss=new ValidationResult("Expire date must be greater than or equal to Today");
            res.Add(mss);

        }
        return res; 
    }
}

Ответ 3

В значительной степени заимствуя ответы Александра Гора и Хайме Марина на связанный вопрос StackOverflow 1, я создал пять классов, которые позволяют сравнивать два поля в одной модели с использованием операторов GT, GE, EQ, LE и LT при условии, что они реализуют IComparable. Так, например, его можно использовать для пар дат, времени, целых чисел и строк.

Было бы неплохо объединить их все в один класс и использовать оператор в качестве аргумента, но я не знаю как. Я оставил три исключения как есть, потому что, если их выбросить, они действительно представляют проблему проектирования формы, а не проблему пользовательского ввода.

Вы просто используете его в своей модели следующим образом, и файл с пятью классами выглядит следующим образом:

    [Required(ErrorMessage = "Start date is required.")]
    public DateTime CalendarStartDate { get; set; }

    [Required(ErrorMessage = "End date is required.")]
    [AttributeGreaterThanOrEqual("CalendarStartDate", 
        ErrorMessage = "The Calendar end date must be on or after the Calendar start date.")]
    public DateTime CalendarEndDate { get; set; }


using System;
using System.ComponentModel.DataAnnotations;

//Contains GT, GE, EQ, LE, and LT validations for types that implement IComparable interface.
///info/1263463/custom-validation-attributes-comparing-two-properties-in-the-same-model

namespace DateComparisons.Validations
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
    public class AttributeGreaterThan : ValidationAttribute
    {
        private readonly string _comparisonProperty;
        public AttributeGreaterThan(string comparisonProperty){_comparisonProperty = comparisonProperty;}

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if(value==null) return new ValidationResult("Invalid entry");

        ErrorMessage = ErrorMessageString;

        if (value.GetType() == typeof(IComparable)) throw new ArgumentException("value has not implemented IComparable interface");
        var currentValue = (IComparable)value;

        var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
        if (property == null) throw new ArgumentException("Comparison property with this name not found");

        var comparisonValue = property.GetValue(validationContext.ObjectInstance);
        if(!ReferenceEquals(value.GetType(), comparisonValue.GetType()))
            throw new ArgumentException("The types of the fields to compare are not the same.");

        return currentValue.CompareTo((IComparable)comparisonValue) > 0 ? ValidationResult.Success : new ValidationResult(ErrorMessage);
    }
}

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class AttributeGreaterThanOrEqual : ValidationAttribute
{
    private readonly string _comparisonProperty;
    public AttributeGreaterThanOrEqual(string comparisonProperty) { _comparisonProperty = comparisonProperty; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null) return new ValidationResult("Invalid entry");
        ErrorMessage = ErrorMessageString;

        if (value.GetType() == typeof(IComparable)) throw new ArgumentException("value has not implemented IComparable interface");
        var currentValue = (IComparable)value;

        var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
        if (property == null) throw new ArgumentException("Comparison property with this name not found");

        var comparisonValue = property.GetValue(validationContext.ObjectInstance);
        if (!ReferenceEquals(value.GetType(), comparisonValue.GetType()))
            throw new ArgumentException("The types of the fields to compare are not the same.");

        return currentValue.CompareTo((IComparable)comparisonValue) >= 0 ? ValidationResult.Success : new ValidationResult(ErrorMessage);

    }
}

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class AttributeEqual : ValidationAttribute
{
    private readonly string _comparisonProperty;
    public AttributeEqual(string comparisonProperty) { _comparisonProperty = comparisonProperty; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null) return new ValidationResult("Invalid entry");
        ErrorMessage = ErrorMessageString;

        if (value.GetType() == typeof(IComparable)) throw new ArgumentException("value has not implemented IComparable interface");
        var currentValue = (IComparable)value;

        var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
        if (property == null) throw new ArgumentException("Comparison property with this name not found");

        var comparisonValue = property.GetValue(validationContext.ObjectInstance);
        if (!ReferenceEquals(value.GetType(), comparisonValue.GetType()))
            throw new ArgumentException("The types of the fields to compare are not the same.");

        return currentValue.CompareTo((IComparable)comparisonValue) == 0 ? ValidationResult.Success : new ValidationResult(ErrorMessage);
    }
}

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class AttributeLessThanOrEqual : ValidationAttribute
{
    private readonly string _comparisonProperty;
    public AttributeLessThanOrEqual(string comparisonProperty) { _comparisonProperty = comparisonProperty; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null) return new ValidationResult("Invalid entry");
        ErrorMessage = ErrorMessageString;

        if (value.GetType() == typeof(IComparable)) throw new ArgumentException("value has not implemented IComparable interface");
        var currentValue = (IComparable)value;

        var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
        if (property == null) throw new ArgumentException("Comparison property with this name not found");

        var comparisonValue = property.GetValue(validationContext.ObjectInstance);
        if (!ReferenceEquals(value.GetType(), comparisonValue.GetType()))
            throw new ArgumentException("The types of the fields to compare are not the same.");

        return currentValue.CompareTo((IComparable)comparisonValue) <= 0 ? ValidationResult.Success : new ValidationResult(ErrorMessage);
    }
}

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class AttributeLessThan : ValidationAttribute
{
    private readonly string _comparisonProperty;
    public AttributeLessThan(string comparisonProperty) { _comparisonProperty = comparisonProperty; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null) return new ValidationResult("Invalid entry");
        ErrorMessage = ErrorMessageString;

        if (value.GetType() == typeof(IComparable)) throw new ArgumentException("value has not implemented IComparable interface");
        var currentValue = (IComparable)value;

        var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
        if (property == null) throw new ArgumentException("Comparison property with this name not found");

        var comparisonValue = property.GetValue(validationContext.ObjectInstance);
        if (!ReferenceEquals(value.GetType(), comparisonValue.GetType()))
            throw new ArgumentException("The types of the fields to compare are not the same.");

        return currentValue.CompareTo((IComparable)comparisonValue) < 0 ? ValidationResult.Success : new ValidationResult(ErrorMessage);
    }
}

}