[ASP.NET MVC] 如何調整 ASP.NET MVC 3 的 Client 驗證順序

如何調整 ASP.NET MVC 3 的 Client 驗證順序

 

(我的第一Post~~~排版可能不好以後慢慢練習)

前陣子遇到一個小問題,花了點時間試一下,趁還有記憶寫下來。手上有個專案是MVC 2 ,不過說實在是個MVC 2跟 3 的混和體。

為了未來著想(已經計畫要升級),在調整需求的時候順便把原本用的 MicrosoftMvcValidation.js 換到 jquery.validate.js,畢竟MicrosoftMvcValidation.js 已經在MVC 4消失了。不過就遇到這個問題, Client的驗證順序有差異。

專案中用了Required、RegularExpression與StringLength 三種,我做了些實驗,結果是

Server 驗證順序:Required –> StringLength –> RegularExpression

MVC2–MicrosoftMvcValidation Client驗證順序:Required –> StringLength –> RegularExpression

MVC3–jquery.validate Client驗證順序:Required –> RegularExpression –> StringLength

其實我原本沒注意到,不過我們親愛的QA Team發現了它,當然我就來調整一下,目的就是讓它行為跟原來一樣,當然也讓Client 跟 Server行為相同。

以下用了MVC 3專案做實驗,採預設的Internet Application,挑了 RegisterModel 中的 Email來當範例。

 

原來是

   1:    public class RegisterModel
   2:      {
   3:          
   4:          [Required]
   5:          [DataType(DataType.EmailAddress)]
   6:          [Display(Name = "Email address")]
   7:          public string Email { get; set; }

 

 

加上 RegularExpression 與 StringLength (長度介於10~25) 改為

   1:   
   2:      public class RegisterModel
   3:      {
   4:       
   5:          [Required(ErrorMessage = "Require Email~~~")]
   6:          [RegularExpression(@"\w+([-+.']\w+)*[-]?@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "RegularExpression Error~~~")]
   7:          [StringLength(25, MinimumLength = 10, ErrorMessage = "StringLength Error~~~")]
   8:          [DataType(DataType.EmailAddress)]
   9:          [Display(Name = "Email address")]
  10:          public string Email { get; set; }

 

 

關掉Web Config中 ClientValidationEnabled  或是直接Mark掉

   1:  <add key="ClientValidationEnabled" value="false" />

 

 

首先先來看看Server驗證的順序:

1.都不填寫 觸發了 Required

image

2.長度小於10 格式也不合法 先觸發 StringLength

image

3.長度小於10 格式合法 觸發 StringLength

image

4.長度大於10 格式不合法 觸發 RegularExpression

image

5.長度大於10 格式合法 當然就Pass了

image

 

再來實驗 Client 驗證順序 ClientValidationEnabled 記得打開

1.都不填寫 觸發了 Required

image

2.長度小於10 格式也不合法 先觸發 RegularExpression

image

3.長度小於10 格式合法 觸發 StringLength

image

4.長度大於10 格式不合法 觸發 RegularExpression

image

5.長度大於10 格式合法 Pass

image

 

如果比對一下2的結果,可以看到在預設不調整的狀況下,其實是不同的。

那要如何調整成一樣呢,其實問題出在jquery.validate.js 上,它的處理造成了二者的差異。

先來看一下原來的原始碼

 

記得把頁面中

<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
改成
<script src="<%: Url.Content("~/Scripts/jquery.validate.js") %>" type="text/javascript"></script>

然後把中斷點下在 158 行

   1:      var data = $.validator.normalizeRules(  
   2:          $.extend(
   3:              {},
   4:              $.validator.metadataRules(element),
   5:              $.validator.classRules(element),
   6:              $.validator.attributeRules(element),
   7:              $.validator.staticRules(element)
   8:          ), element);
   9:   
  10:          // make sure required is at front
  11:          if (data.required) {  //<---這在Line 158 
  12:              var param = data.required;
  13:              delete data.required;
  14:              data = $.extend({required: param}, data);
  15:          }
  16:   
  17:          return data;

 

 

可以看到,如果都不調整下,之後會處理的順序會是 RegularExpression –> StringLength –> Required

注意:因為我 StringLength 給了 Max 與 Min  所以其實這邊用到的是 rangelength  如果只填了 Max 用的是 maxlength

 

image

不過 158 以後的那一段,強制將Required放到了第一個,所以就得到我們實驗時Client 驗證的順序。

image

 

而我要讓順序變為Required –> StringLength –> RegularExpression,因此偷學了一下原來調整Required的寫法變為以下的程式碼

   1:          var data = $.validator.normalizeRules(
   2:          $.extend(
   3:              {},
   4:              $.validator.metadataRules(element),
   5:              $.validator.classRules(element),
   6:              $.validator.attributeRules(element),
   7:              $.validator.staticRules(element)
   8:          ), element);
   9:   
  10:          // make rangelength be senond      <--因為要讓它排第二位 所以要先處理  越後面處理的 順序會排越前面
  11:          if (data.rangelength != undefined) {
  12:              var param = data.rangelength;
  13:              delete data.rangelength;
  14:              data = $.extend({ rangelength: param }, data);
  15:          }
  16:   
  17:          // make sure required is at front
  18:          if (data.required) {
  19:              var param = data.required;
  20:              delete data.required;
  21:              data = $.extend({required: param}, data);
  22:          }

 

 

再跑一次,長度小於10 格式也不合法 先觸發 StringLength了。

image

搞定 收工~~謝謝觀賞

 

備註:

1.其實我不愛改標準的東西,以後維護就很麻煩。如果有前輩找到人家的外掛煩請告訴小弟。

2.這篇只討論了Required、StringLength與RegularExpression, 其他的我就沒有再做實驗了,不過概念相同。