3

開始日と終了日にビューモデルを使用し、データ注釈を使用して検証を使用しています。検証ルールは次のとおりです。

  1. 開始日は終了日より前、null、空白であってはなりません
  2. 終了日は、開始日より前で、DateTime.Now より前で、null 以外、空白であってはなりません

次のビュー モデルは、startdate および enddate プロパティで構成されます。混乱は、以下のコードで StartEndDateRange データ注釈に EndDate 値の値を渡し、EndDate のデータ注釈に StartDate 値を渡すにはどうすればよいかということです。

  public class StartEndDate
    {
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [StartEndDateRange("2000/01/01", "value of end date properties")]
        public DateTime StartDate { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [StartEndDateRange("value of startdate properties", DateTime.Now.ToString("yyyy/MM/dd"))]
        public DateTime EndDate { get; set; }


    }

    public class StartEndDateRangeAttribute : ValidationAttribute
    {
        private const string DateFormat = "yyyy/MM/dd";
        private const string DefaultErrorMessage =
     "'{0}' must be a date between {1:d} and {2:d}.";

        public DateTime MinDate { get; set; }
        public DateTime MaxDate { get; set; }

        public StartEndDateRangeAttribute(string minDate, string maxDate)
            : base(DefaultErrorMessage)
        {
            MinDate = ParseDate(minDate);
            MaxDate = ParseDate(maxDate);
        }

        public override bool IsValid(object value)
        {
            if (value == null || !(value is DateTime))
            {
                return true;
            }
            DateTime dateValue = (DateTime)value;
            return MinDate <= dateValue && dateValue <= MaxDate;
        }
        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentCulture,
     ErrorMessageString,
                name, MinDate, MaxDate);
        }

        private static DateTime ParseDate(string dateValue)
        {
            return DateTime.ParseExact(dateValue, DateFormat,
     CultureInfo.InvariantCulture);
        }
    }
4

3 に答える 3

3

2 つの異なる検証属性を作成します。ワンDateBefore・アンド・アナザーDataAfter

から検証中のモデルのプロパティを取得できますvalidationContext

DateBefore行うには

protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
    PropertyInfo endDateProperty= validationContext.ObjectType.GetProperty("EndDate");
    ...
}

によって値を取得します

var endDate = endDateProperty.GetValue(validationContext.ObjectInstance, null);

と を比較valueendDateます。

編集

もう少しコード

public class BeforeEndDateAttribute : ValidationAttribute{
    public string EndDatePropertyName { get; set; }
    public string StartDate { get; set; }


    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        PropertyInfo endDateProperty = validationContext.ObjectType.GetProperty(EndDatePropertyName);

        DateTime endDate = (DateTime) endDateProperty.GetValue(validationContext.ObjectInstance, null);

        var startDate = DateTime.Parse(StartDate);

        // Do comparison
        // return ValidationResult.Success; // if success
        return new ValidationResult("Error"); // if fail
    }

}

そして次のように使用します:

public class MyModel
{
    [BeforeEndDate(EndDatePropertyName = "EndDate", StartDate = "2000/01/01")]
    public DateTime StartDate { get; set; }

    // [AfterStartDate(StartDatePropertyName = "StartDate", EndDate = "2020/01/01")]
    public DateTime EndDate { get; set; }
}
于 2012-08-27T10:36:24.527 に答える
1

これを 1 つの検証属性で実装する方が簡単ですDateRange

ただし、そうしたくない場合は、 をオーバーライドIsValid(Object, ValidationContext)し、検証対象のオブジェクト タイプを から抽出し、検証対象ValidationContext.ObjectTypeのプロパティを取得してValidationContext.MemberNameから、属性から値を読み取る必要があります。

于 2012-08-27T10:22:14.817 に答える
1

クラスに を実装することをお勧めしますIValidatableObjectが、唯一のことは、クライアント側の検証を自分で行う必要があることです。

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

    [Required]    
    public DateTime EndDate { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
       // do the validations
    }
}
于 2012-08-27T11:28:48.760 に答える