2

我想达到什么目标:

  1. 显示一条针对最小年龄检查失败的单独验证消息和一条针对最大年龄检查的验证消息
  2. 将一个区域中的最小和最大年龄存储为整数。不在 js/ 验证器中……仅在模型中。我希望将其更改为查看配置文件。
  3. 为了使验证与 jquery 不显眼和服务器端一起工作,并在一个地方针对模型(和 obv 一些 jquery)
  4. 使用数据注释启用
  5. 我想检查 DOB 作为日期时间,而不是让用户将年龄作为 int 输入。如果我这样做了,我可以使用 [Min] 符号和 [Max] 符号来表示年龄。这还不够好。
  6. 为什么我不使用范围表示法。我想为每个最小失败和最大失败触发不同的验证消息。我看着这个,没有看。我还必须将范围作为日期时间及其静态或其他内容传递,因此我无法完成 DateTime.Now.AddYears(-90) 之类的操作。

我的问题

  1. 我是 MVC、JQuery 验证和整个 MVC 架构的菜鸟!
  2. 我想出的作品。但是,正如您所看到的,有很多重复的代码,我想符合 DRY。
  3. 我的第一个技巧是将我要检查的值传递到验证消息中。我通过这样做解决了这个问题...

    [MaximumAgeCheck(90,"您最多必须是 {0} 才能申请")]

并在验证属性内

    private readonly int _min;
    private readonly string _defaultErrorMessage = "";
    public MinimumAgeCheck(int min, string defaultErrorMessage)
        : base(defaultErrorMessage)
    {
        _min = min;
        _defaultErrorMessage = defaultErrorMessage.Replace("{0}", _min.ToString());
    }

例如,我像这样使用它..

return new ValidationResult(_defaultErrorMessage);

我知道这不是正确的方法,并且想知道最好的方法是什么?

第二次破解!

我传入了两个验证参数,我希望能够在 jQuery.validator.addMethod... 方法中访问它们。

我尝试通过执行以下操作来访问这些参数... params.[thevalueiadded]、params[0]...等,我什至将参数注销到 console.log 但它从未向我显示所有参数,只显示第一个值作为一个字符串!

我的解决方法是将 javascript 变量存储在顶部并从 adapters.add 加载它们。

我可能没有什么意义,所以这里是代码,它有效......我警告你,它很乱!

模型属性和数据注释

[Required(ErrorMessage = "Date of birth required")]
        [Display(Name = "Date of Birth")]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
        [DataType(DataType.DateTime, ErrorMessage = "Date of birth should be in dd/mm/yyyy format")]
        [MinimumAgeCheck(18,"You have to be at least {0} to apply")]
        [MaximumAgeCheck(90,"You have to be at most {0} to apply")]
        public DateTime? DateOfBirth { get; set; }

最小年龄检查和最大年龄检查

验证属性

public class MinimumAgeCheck : ValidationAttribute, IClientValidatable
    {
        private readonly int _min;
        private readonly string _defaultErrorMessage = "";
        public MinimumAgeCheck(int min, string defaultErrorMessage)
            : base(defaultErrorMessage)
        {
            _min = min;
            _defaultErrorMessage = defaultErrorMessage.Replace("{0}", _min.ToString());
        }


        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DateTime dtV = (DateTime)value;
            long lTicks = DateTime.Now.Ticks - dtV.Ticks;
            DateTime dtAge = new DateTime(lTicks);

            if (!(dtAge.Year >= _min && dtAge.Year <= 30))
            {
                return new ValidationResult(_defaultErrorMessage);
            }
            return ValidationResult.Success;
        }

        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, _min);
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule mcvrTwo = new ModelClientValidationRule();
            mcvrTwo.ValidationType = "checkminimumage";
            mcvrTwo.ErrorMessage = _defaultErrorMessage;
            mcvrTwo.ValidationParameters.Add("todaysdate", DateTime.Now.ToString("dd/MM/yyyy"));
            mcvrTwo.ValidationParameters.Add("lowerage", _min.ToString());

            return new List<ModelClientValidationRule> { mcvrTwo };
        }
    }


  public class MaximumAgeCheck : ValidationAttribute, IClientValidatable
    {
        private readonly int Max;
        private readonly string _defaultErrorMessage = "";
        public MaximumAgeCheck(int max, string defaultErrorMessage)
            : base(defaultErrorMessage)
        {
            Max = max;
            _defaultErrorMessage = defaultErrorMessage.Replace("{0}", Max.ToString());
        }


        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DateTime dtV = (DateTime)value;
            long lTicks = DateTime.Now.Ticks - dtV.Ticks;
            DateTime dtAge = new DateTime(lTicks);

            if (!(dtAge.Year >= Max && dtAge.Year <= 30))
            {
                return new ValidationResult(_defaultErrorMessage);
            }
            return ValidationResult.Success;
        }

        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,Max);
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule mcvrTwo = new ModelClientValidationRule();
            mcvrTwo.ValidationType = "checkmaximumage";
            mcvrTwo.ErrorMessage = _defaultErrorMessage;
            mcvrTwo.ValidationParameters.Add("todaysdate", DateTime.Now.ToString("dd/MM/yyyy"));
            mcvrTwo.ValidationParameters.Add("upperage", Max.ToString());

            return new List<ModelClientValidationRule> { mcvrTwo };
        }
    }

jQuery

(function ($) {

    var mintodaysDateVal;
    var maxtodaysDateVal;
    var lowerageVal;
    var upperageVal;
    jQuery.validator.unobtrusive.adapters.add("checkminimumage", ['lowerage', 'todaysdate', 'upperage'], function (options) {
        options.rules["checkminimumage"] = options.params;

        mintodaysDateVal = options.params.todaysdate;
        lowerageVal = options.params.lowerage;

        options.messages["checkminimumage"] = options.message;
    });



    jQuery.validator.addMethod("checkminimumage", function (value, element, params) {

        var currDate = mintodaysDateVal;
        var sdoc = currDate.split('/');
        var dobDate = value;
        var sdob = dobDate.split('/');



        //pass year,month,date in new Date object.
        var vDOB = new Date(sdob[2], sdob[1] - 1, sdob[0]);
        var vDOC = new Date(sdoc[2], sdoc[1] - 1, sdoc[0]);
        //getAge user define function to calculate age.

        var vYrs = getAge(vDOB, vDOC);
        var result = false;
        if (vYrs >= lowerageVal) { result = true; }
        return result;
    });



    jQuery.validator.unobtrusive.adapters.add("checkmaximumage", ['lowerage', 'todaysdate', 'upperage'], function (options) {
        options.rules["checkmaximumage"] = options.params;

        maxtodaysDateVal = options.params.todaysdate;
        upperageVal = options.params.upperage;

        options.messages["checkmaximumage"] = options.message;
    });



    jQuery.validator.addMethod("checkmaximumage", function (value, element, params) {
        var currDate = maxtodaysDateVal;
        var sdoc = currDate.split('/');
        var dobDate = value;
        var sdob = dobDate.split('/');

        var vDOB = new Date(sdob[2], sdob[1] - 1, sdob[0]);
        var vDOC = new Date(sdoc[2], sdoc[1] - 1, sdoc[0]);

        var vYrs = getAge(vDOB, vDOC);
        var result = false;
        if (vYrs <= upperageVal) { result = true; }
        return result;
    });


    function getAge(oldDate, currDate) {
        return currDate.getFullYear() - oldDate.getFullYear();
    }
} (jQuery));

我希望这是有道理的,我已经阅读了它并且它很乱码......所以我很乐意回答任何评论。

4

2 回答 2

0

真正有用的代码,但是 ValidationResult IsValid 方法有一些错误。它不处理未来日期或空白日期。另外,它似乎对 30 岁有硬编码限制 - 看起来是调试代码?无论如何,我为我的代码解决了这些问题,并提出了以下问题:

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            return new ValidationResult(_defaultErrorMessage);
        }

        DateTime dtV = (DateTime)value;
        long lTicks = DateTime.Now.Ticks - dtV.Ticks;
        if (lTicks < 0)
        {
            return new ValidationResult(_defaultErrorMessage);
        }

        DateTime dtAge = new DateTime(lTicks);

        if (!(dtAge.Year >= _min ))
        {
            return new ValidationResult(_defaultErrorMessage);
        }
        return ValidationResult.Success;
    }
于 2012-10-04T09:13:03.357 回答
0

看看MVC Foolproof Validation库。你可以在 NuGet 中找到它。

它几乎具有您需要的所有验证,并通过数据注释添加。它将很好地集成到不显眼的客户端验证中。

于 2012-10-04T09:23:59.173 回答