2012-08-27 48 views
3

我使用視圖模型開始和結束日期並使用數據註釋進行驗證。驗證規則是:開始和結束日期的數據註釋

  1. 開始日期不應該大於結束日期和不爲空,空
  2. 結束日期應不小於開始日期和不低於 DateTime.Now並且不爲空,空

以下視圖模型由startdate和enddate屬性組成。混亂的是,我怎麼能在下面的代碼在結束日期的數據註解傳遞結束日期值的值StartEndDateRange數據註釋和起始日期值:

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); 
     } 
    } 

回答

1

它更容易實現這一個驗證屬性DateRange

但是,如果你不想,你就必須重寫IsValid(Object, ValidationContext),提取對象類型從ValidationContext.ObjectType被驗證,獲得通過ValidationContext.MemberName正在驗證它的屬性,然後從屬性的讀取值。

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; } 
} 
+0

謝謝我明白了。但是我必須在dataannotation中爲結束日期的值放置:'[StartEndDateRange(「2000/01/01」,「結束日期屬性的值」)]' – CodeManiac

+0

取代*「結束日期屬性的值」*?沒有。只是'[StartEndDateRange(「2000/01/01」)]'。告訴我你是否需要更多的解釋。 – Mohayemin

+0

@CodeManiac:編輯 – Mohayemin

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 
    } 
} 
相關問題