数据注释,不显眼的验证。最小年龄,最大年龄

数据注释,不显眼的验证。最小年龄,最大年龄

问题描述:

什么我想实现:数据注释,不显眼的验证。最小年龄,最大年龄

  1. 要显示一个单独的验证消息未能最低年龄支票和一个最大年龄检查
  2. 的最小和最大年龄存储在一个区域作为整数。不在js /验证器中......只在模型中。我希望改变看一个配置文件。
  3. 为了验证与jQuery的不显眼和服务器端工作,并在对模型中的一个位置(和OBV一些jQuery的)
  4. 要使用数据注释
  5. 我想核对DOB作为启用日期时间,而不是用户把年龄作为一个整数。如果我这样做了,我可以使用[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 ...方法中访问。

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

我的工作是将JavaScript变量存储在顶部,并从adapters.add加载它们。

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

Model属性和数据注解

[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)); 

我希望这是有道理的,我读它和它相当乱码...所以我很乐意回答任何评论。

确实有用的代码,但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; 
    } 

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

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