【问题标题】:Data Annotation for start and end date开始和结束日期的数据注释
【发布时间】:2012-08-27 10:09:49
【问题描述】:

我将视图模型用于开始和结束日期,并使用数据注释进行验证。验证规则是:

  1. 开始日期不应大于结束日期且不为空,空白
  2. 结束日期不得早于开始日期且不得小于 DateTime.Now 且不为空,为空

以下视图模型由 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);
        }
    }

【问题讨论】:

    标签: c# asp.net-mvc-3 data-annotations


    【解决方案1】:

    创建两个不同的验证属性。一个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; }
    }
    

    【讨论】:

    • 谢谢我知道了。但是我必须在数据注释中放置结束日期的值:[StartEndDateRange("2000/01/01", "value of end date properties")]
    • 代替“结束日期属性的值”?没有。只是[StartEndDateRange("2000/01/01")]。告诉我你是否需要更多解释。
    【解决方案2】:

    在一个验证属性DateRange 中实现这一点更容易。

    但如果您不想这样做,则必须覆盖 IsValid(Object, ValidationContext),从 ValidationContext.ObjectType 提取正在验证的对象类型,使其属性由 ValidationContext.MemberName 验证,然后从属性中读取值。

    【讨论】:

      【解决方案3】:

      我可能会建议您在课堂上实现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-19
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 2021-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多