[ASP.NET][MVC] ASP.NET MVC (6) : 資料驗證 (2) Model Validation

在前一篇文章中,我們撰寫了一個 server-side 的 validation 方法,雖然解決了驗證的問題,但是和時下流行的 client-side validation 不符,而且 server-side 不應該只是檢查資料型別這件事而已,它應該要解決更複雜的問題,而 client-side validation 專司處理簡單的驗證問題...

在前一篇文章中,我們撰寫了一個 server-side 的 validation 方法,雖然解決了驗證的問題,但是和時下流行的 client-side validation 不符,而且 server-side 不應該只是檢查資料型別這件事而已,它應該要解決更複雜的問題,而 client-side validation 專司處理簡單的驗證問題,只是 ASP.NET MVC 本身並未內建自動化的 client validation,但它仍然具備 client validation 的能力,因為它的兄弟 ASP.NET Dynamic Data 提供了這樣的功能,ASP.NET MVC 則是將它引用進來而已。

Dynamic Data 所提供的功能稱為 Model Validation,它可以在 Model 層中直接加上驗證指令,並且配合用戶端的 Client-side library 做協同處理,以達到 client-validation 的功能。要使用 Model Validation,我們首先要有一個 Model,所以我們建了這樣的一個 Model,放在 Models 資料夾:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.ComponentModel;
   6: using System.ComponentModel.DataAnnotations;
   7:  
   8: namespace MvcApplication1.Models
   9: {
  10:     public class ValueAddModel
  11:     {
  12:         [Required(ErrorMessage = "This field is required.")]
  13:         [RegularExpression("[0-9]*", ErrorMessage = "This field requires numeric character.")]
  14:         public int Value1 { get; set; }
  15:         [Required(ErrorMessage = "This field is required.")]
  16:         [RegularExpression("[0-9]*", ErrorMessage = "This field requires numeric character.")]
  17:         public int Value2 { get; set; }
  18:  
  19:         public int Add()
  20:         {
  21:             return this.Value1 + this.Value2;
  22:         }
  23:     }
  24: }

請注意,在這個 Model 中,我們加了對 System.ComponentModel 和 System.ComponentModel.DataAnnotations 兩個命名空間的引用,Model Validation 則是由它們來提供,而我們針對要驗證的 Value1 和 Value2 都加上了 [Required] 特徵,以及為了驗證值為數字所需的 [RegularExpression] 特徵項等,並且設定了錯誤的訊息。然後,修改 MyController,直接取得 ModelState.IsValid 來判斷是否驗證通過即可。另外,參數換成 Model.ValueAddModel,而不是再以實值參數為主,理由是 Model Validation 所需的資料都在 Model 中,並且 ASP.NET MVC  會自動將表單的值設定在 Model 中:

   1: [HttpPost]
   2: public ActionResult Index(Models.ValueAddModel Model)
   3: {
   4:     if (this.ModelState.IsValid)
   5:     {
   6:         TempData["result"] = Model.Add();
   7:         return RedirectToAction("PostData");
   8:     }
   9:     else
  10:         return View();
  11: }

然後,修改 Index.cshtml:

   1: @model MvcApplication1.Models.ValueAddModel
   2: @{
   3:     ViewBag.Title = "Index";
   4: }
   5:  
   6: <h2>Index</h2>
   7:  
   8: <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
   1:  
   2: <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript">
</script>
   9:  
  10: @{ Html.EnableClientValidation(); }
  11: @{ Html.BeginForm("Index", "My", FormMethod.Post); }
  12:  
  13: <p>
  14:    Value1: @Html.TextBox("Value1")
  15:    @Html.ValidationMessage("Value1", "*")
  16: </p>
  17: <p>
  18:    Value2: @Html.TextBox("Value2")
  19:    @Html.ValidationMessage("Value2", "*")
  20: </p>
  21: <p>
  22:    @Html.ValidationSummary()
  23: </p>
  24:  
  25: <input type="submit" value=" OK " />
  26:  
  27: @{ Html.EndForm(); }

在 View 中的修改,主要是以加入 client-side validation 為主,首先是加入指令碼,這兩個指令碼在專案建立時就已經在  /scripts 資料夾中,所以直接加到 View 中就行了,然後是使用 @Html.EnableClientValidation() 啟用用戶端的驗證,其他的基本上可以不變。

執行它,並且輸入錯的資料,你會發現不再是 server-side validation:

image

PS: 如果是使用 MVC 2 的話,指令碼和 MVC 3 的不一樣,MVC 2 使用的是 MicrosoftAjax.js 和 MicrosoftMvcValidation.js,但 MVC 3 用的是 jquery.validate.min.js 和 jquery.validate.unobtrusive.min.js。

 

Reference:

http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-6