在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现Model两个中两个属性值的比较验证
具体应用场景为:要对两个属性值的大小进行验证
代码如下所示:
/// <summary> /// Specifies that the field must compare favourably with the named field, if objects to check are not of the same type /// false will be return /// </summary> public class CompareValuesAttribute : ValidationAttribute { /// <summary> /// The other property to compare to /// </summary> public string OtherProperty { get; set; } public CompareValues Criteria { get; set; } /// <summary> /// Creates the attribute /// </summary> /// <param name="otherProperty">The other property to compare to</param> public CompareValuesAttribute(string otherProperty, CompareValues criteria) { if (otherProperty == null) throw new ArgumentNullException("otherProperty"); OtherProperty = otherProperty; Criteria = criteria; } /// <summary> /// Determines whether the specified value of the object is valid. For this to be the case, the objects must be of the same type /// and satisfy the comparison criteria. Null values will return false in all cases except when both /// objects are null. The objects will need to implement IComparable for the GreaterThan,LessThan,GreatThanOrEqualTo and LessThanOrEqualTo instances /// </summary> /// <param name="value">The value of the object to validate</param> /// <param name="validationContext">The validation context</param> /// <returns>A validation result if the object is invalid, null if the object is valid</returns> protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // the the other property var property = validationContext.ObjectType.GetProperty(OtherProperty); // check it is not null if (property == null) return new ValidationResult(String.Format("Unknown property: {0}.", OtherProperty)); // check types var memberName = validationContext.ObjectType.GetProperties().Where(p => p.GetCustomAttributes(false).OfType<DisplayAttribute>().Any(a => a.Name == validationContext.DisplayName)).Select(p => p.Name).FirstOrDefault(); if (memberName == null) { memberName = validationContext.DisplayName; } if (validationContext.ObjectType.GetProperty(memberName).PropertyType != property.PropertyType) return new ValidationResult(String.Format("The types of {0} and {1} must be the same.", memberName, OtherProperty)); // get the other value var other = property.GetValue(validationContext.ObjectInstance, null); // equals to comparison, if (Criteria == CompareValues.EqualTo) { if (Object.Equals(value, other)) return null; } else if (Criteria == CompareValues.NotEqualTo) { if (!Object.Equals(value, other)) return null; } else { // check that both objects are IComparables if (!(value is IComparable) || !(other is IComparable)) return new ValidationResult(String.Format("{0} and {1} must both implement IComparable", validationContext.DisplayName, OtherProperty)); // compare the objects var result = Comparer.Default.Compare(value, other); switch (Criteria) { case CompareValues.GreaterThan: if (result > 0) return null; break; case CompareValues.LessThan: if (result < 0) return null; break; case CompareValues.GreatThanOrEqualTo: if (result >= 0) return null; break; case CompareValues.LessThanOrEqualTo: if (result <= 0) return null; break; } } // got this far must mean the items don‘t meet the comparison criteria return new ValidationResult(ErrorMessage); } } /// <summary> /// Indicates a comparison criteria used by the CompareValues attribute /// </summary> public enum CompareValues { EqualTo, NotEqualTo, GreaterThan, LessThan, GreatThanOrEqualTo, LessThanOrEqualTo }
应用的时候直接在指定的属性上添加此CompareValuesAttribute标签即可
【注:第一个参数是要与之比较的属性名,第二个参数表示两个属性值之间的大小关系,第三个参数表示错误提示信息】
public class EricSunModel { [Display(Name = "Ready Time")] public string ReadyTime { get; set; } [CompareValues("ReadyTime", CompareValues.GreaterThan, ErrorMessage = "Close time must be later than ready time")] [Display(Name = "Close Time")] public string CloseTime { get; set; } }
更多细节可以参考如下链接:
http://cncrrnt.com/blog/index.php/2011/01/custom-validationattribute-for-comparing-properties/