2

什麼我想實現:數據註釋,不顯眼的驗證。最小年齡,最大年齡

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

我希望這是有道理的,我讀它和它相當亂碼...所以我很樂意回答任何評論。

回答

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; 
    } 
0

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

它有幾乎所有您需要的驗證,並通過數據註釋添加。它將很好地整合到不顯眼的客戶端驗證中。