ValidationAttribute 自定义多属性验证扩展

  • 发布日期:2016年3月22日
  • 新闻类别: ASP.net C#
  • 查看:449

项目中有个时间段的验证,要求截止日期必须超过开始日期30天。这个就牵扯到两个字段的比对了,就要传入多个参数:

C#代码段:


public class CompareToDateAttribute : ValidationAttribute, IClientValidatable
    {

        public CompareToDateAttribute(int dates, string propertyName) : base("{0}必须大于{1}{2}天")
        {
            this.PropertyName = propertyName;
            this.Dates = dates;
        }

       
        public string PropertyName { get; private set; }
        public int Dates { get; private set; }

    

        public string FormatErrorMessage(string name, string otherName, int dates)
        {
            return string.Format(ErrorMessageString, name, otherName, dates);
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DateTime expireDate  = Convert.ToDateTime(value);
            DateTime startDate = Convert.ToDateTime(GetSecondComparable(validationContext));

         
            if ((expireDate-startDate).TotalDays <= Dates)
            {
                object obj = validationContext.ObjectInstance;
                var thing = obj.GetType().GetProperty(PropertyName);
                var displayName = (DisplayAttribute)Attribute.GetCustomAttribute(thing, typeof(DisplayAttribute));

                return new ValidationResult(
                    FormatErrorMessage(validationContext.DisplayName, displayName.GetName(), Dates));
            }
         
            return ValidationResult.Success;
        }

        protected IComparable GetSecondComparable(ValidationContext validationContext)
        {
            var propertyInfo = validationContext
                                  .ObjectType
                                  .GetProperty(PropertyName);
            if (propertyInfo != null)
            {
                var secondValue = propertyInfo.GetValue(
                    validationContext.ObjectInstance, null);
                return secondValue as IComparable;
            }
            return null;
        }

       
        //new method
        public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {

            return new[]
           {
                new ModelClientValidationRangeDateRule(
                     FormatErrorMessage(metadata.GetDisplayName(), "项目截目日期", Dates), Dates, PropertyName)
            };         

        }


        public class ModelClientValidationRangeDateRule : ModelClientValidationRule
        {
            public ModelClientValidationRangeDateRule(string errorMessage, int dates, string toName)
            {
                ErrorMessage = errorMessage;
                ValidationType = "comparetodate";

                ValidationParameters["day"] = dates.ToString();
                ValidationParameters["to"] = toName;

            }
        }

    }

这里有个问题不能解决:就是生成前端的提示信息时,怎么动态的加载第二个属性,这里我暂时是写死了。

 

javascript 部份扩展:


(function ($) {
            // The validator function 只有在type="text"时才有效
            $.validator.addMethod('comparetodate', function (value, element, param) {
                console.log(param);

                var startDate = $("input[name='"+param.to+"']").val();
                var date1 = new Date(startDate);
                var date2 = new Date(value);

                var date_diff = Math.abs(date2.getTime() - date1.getTime()) / 86400000;
            
                if (!value) {
                    return true; // not testing 'is required' here!
                }

                return param.day < date_diff;
            });

            // The adapter to support ASP.NET MVC unobtrusive validation
            $.validator.unobtrusive.adapters.add('comparetodate', ['day','to'], function (options) {
             //   console.log(options);
               
                var params = {
                    day: options.params.day,
                    to: options.params.to
                };

                options.rules['comparetodate'] = params;
                if (options.message) {
                    options.messages['comparetodate'] = options.message;
                }
            });
        }(jQuery));