public class DateCompare : ValidationAttribute { public String StartDate { get; set; } public String EndDate { get; set; } //Constructor to take in the property names that are supposed to be checked public DateCompare(String startDate,String endDate) { StartDate = startDate; EndDate = endDate; } public override bool IsValid(object value) { var str = value.ToString(); if (string.IsNullOrEmpty(str)) return true; DateTime theEndDate = DateTime.ParseExact(EndDate,"yyyy-MM-dd HH:mm:ss",CultureInfo.InvariantCulture); DateTime theStartDate = DateTime.ParseExact(StartDate,CultureInfo.InvariantCulture).AddMonths(3); return (DateTime.Compare(theStartDate,theEndDate) > 0); } }
我想将此实现到我的验证中
[DateCompare(“StartDate”,“EndDate”,ErrorMessage = “The Deal can only be 3 months long!”)]
我知道我在这里得到了一个错误……但我怎样才能在asp.net mvc中进行这种业务规则验证
解决方法
>创建属性类:
public class DateCompareValidationAttribute : ValidationAttribute,IClientValidatable { public enum CompareType { GreatherThen,GreatherThenOrEqualTo,EqualTo,LessThenOrEqualTo,LessThen } private CompareType _compareType; private DateTime _fromDate; private DateTime _toDate; private string _propertyNameToCompare; public DateCompareValidationAttribute(CompareType compareType,string message,string compareWith = "") { _compareType = compareType; _propertyNameToCompare = compareWith; ErrorMessage = message; } #region IClientValidatable Members /// <summary> /// Generates client validation rules /// </summary> public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata Metadata,ControllerContext context) { ValidateAndGetCompareToProperty(Metadata.ContainerType); var rule = new ModelClientValidationRule(); rule.ErrorMessage = ErrorMessage; rule.ValidationParameters.Add("comparetodate",_propertyNameToCompare); rule.ValidationParameters.Add("comparetype",_compareType); rule.ValidationType = "compare"; yield return rule; } #endregion protected override ValidationResult IsValid(object value,ValidationContext validationContext) { // Have to override IsValid method. If you have any logic for server site validation,put it here. return ValidationResult.Success; } /// <summary> /// verifies that the compare-to property exists and of the right types and returnes this property /// </summary> /// <param name="containerType">Type of the container object</param> /// <returns></returns> private PropertyInfo ValidateAndGetCompareToProperty(Type containerType) { var compareToProperty = containerType.GetProperty(_propertyNameToCompare); if (compareToProperty == null) { string msg = string.Format("Invalid design time usage of {0}. Property {1} is not found in the {2}",this.GetType().FullName,_propertyNameToCompare,containerType.FullName); throw new ArgumentException(msg); } if (compareToProperty.PropertyType != typeof(DateTime) && compareToProperty.PropertyType != typeof(DateTime?)) { string msg = string.Format("Invalid design time usage of {0}. The type of property {1} of the {2} is not DateType",containerType.FullName); throw new ArgumentException(msg); } return compareToProperty; } }
注意:如果要验证时间长度,请向约束器添加另一个参数,并更改此特定类型的比较的枚举数
>将属性添加到字段中,如下所示:[DateCompareValidation(DateCompareValidationAttribute.CompareType.GreatherThenOrEqualTo,“此日期必须在另一个日期或之后”,compareWith:“AnotherDate”)]
>记下生成的html是如何更改的.它应包括验证消息,比较日期的字段名称等.生成的parms将以“data-val-compare”开头.在GetClientValidationRules方法中设置ValidationType =“compare”时,您定义了此“比较”.
>现在您需要匹配javascript代码:添加验证适配器和验证方法.我在这里使用了无限的方法,但你不必这样做.我建议将此代码放在一个单独的javascript文件中,以便此文件与您的属性类一起变得像一个控件,可以在任何地方使用.
$.validator.unobtrusive.adapters.add(
‘compare’,
[‘comparetodate’,‘comparetype’],
function (options) {
options.rules[‘compare’] = options.params;
options.messages[‘compare’] = options.message;
}
);
$.validator.addMethod("compare",function (value,element,parameters) { // value is the actuall value entered // element is the field itself,that contain the the value (in case the value is not enough) var errMsg = ""; // validate parameters to make sure everyting the usage is right if (parameters.comparetodate == undefined) { errMsg = "Compare validation cannot be executed: comparetodate parameter not found"; alert(errMsg); return false; } if (parameters.comparetype == undefined) { errMsg = "Compare validation cannot be executed: comparetype parameter not found"; alert(errMsg); return false; } var compareToDateElement = $('#' + parameters.comparetodate).get(); if (compareToDateElement.length == 0) { errMsg = "Compare validation cannot be executed: Element to compare " + parameters.comparetodate + " not found"; alert(errMsg); return false; } if (compareToDateElement.length > 1) { errMsg = "Compare validation cannot be executed: more then one Element to compare with id " + parameters.comparetodate + " found"; alert(errMsg); return false; } //debugger; if (value && !isNaN(Date.parse(value))) { //validate only the value contains a valid date. For invalid dates and blanks non-custom validation should be used //get date to compare var compareToDateValue = $('#' + parameters.comparetodate).val(); if (compareToDateValue && !isNaN(Date.parse(compareToDateValue))) { //if date to compare is not a valid date,don't validate this switch (parameters.comparetype) { case 'GreatherThen': return new Date(value) > new Date(compareToDateValue); case 'GreatherThenOrEqualTo': return new Date(value) >= new Date(compareToDateValue); case 'EqualTo': return new Date(value) == new Date(compareToDateValue); case 'LessThenOrEqualTo': return new Date(value) <= new Date(compareToDateValue); case 'LessThen': return new Date(value) < new Date(compareToDateValue); default: { errMsg = "Compare validation cannot be executed: '" + parameters.comparetype + "' is invalid for comparetype parameter"; alert(errMsg); return false; } } return true; } else return true; } else return true; });
这只关注客户端不显眼的验证.如果你需要服务器端,你必须在isValid方法的覆盖中有一些逻辑.此外,您可以使用Reflection使用显示属性等生成错误消息,并使消息参数可选.