我使用视图模型来开始和结束日期,并使用数据注释进行验证。验证规则是:
以下View模型由startdate和enddate属性组成。令人困惑的是,如何在下面的代码中传递EndEate的数据注释中的StartEndDateRange数据注释和StartDate值中的EndDate值的值:
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);
}
}
答案 0 :(得分: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);
现在比较value
和endDate
。
多一点代码
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; }
}
答案 1 :(得分:1)
在一个验证属性DateRange
中实现此功能更加容易。
但是,如果您不想,则必须覆盖IsValid(Object, ValidationContext)
,从ValidationContext.ObjectType
提取正在验证的对象类型,并通过{{1}验证其属性是否已经过验证然后从属性中读取值。
答案 2 :(得分: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
}
}