数据注释,不引人注目的验证。最小年龄,最大年龄

时间:2012-04-21 15:19:38

标签: asp.net-mvc-3 validation jquery-validate unobtrusive-validation validationattribute

我想达到什么目的:

  1. 显示未通过最低年龄检查的单独验证消息和最长年龄检查的消息
  2. 将一个区域的最小和最大年龄存储为整数。不在js / validator中...仅在模型中。我希望改变以查看配置文件。
  3. 使用jquery unobtrusive和服务器端进行验证,并在一个地方对抗模型(和obv一些jquery)
  4. 使用数据注释启用
  5. 我想将DOB检查为日期时间,而不是让用户将年龄作为int。如果我这样做,我可以使用[Min]表示法和[Max]表示年龄。这还不够好。
  6. 为什么我没有使用范围表示法。我想为每个最小失败和最大失败发出不同的验证消息。我调查了这个并且没看。我还必须将范围作为日期时间及其静态或其他内容传递给我,例如我无法完成DateTime.Now.AddYears(-90)。
  7. 我的问题

    1. 我是MVC,JQuery验证和整个MVC架构的菜鸟!
    2. 我想出了什么作品。但是,你可以看到有很多重复的代码,我想要遵守DRY。
    3. 我的第一个黑客是将我正在检查的值传入验证消息。我这样做了......

      [MaximumAgeCheck(90,“你必须最多{0}才能申请”))

    4. 并在验证属性

          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] ...等,我甚至将params登出到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));
      

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

2 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分:0)

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

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