ASP.NET mvc的最好的優點之一就是支持Model驗證,這個特性很方便你可以選擇在定義Model的時候在欄位中採用特性進行註解約定,也可以在代碼中自己進行手動驗證。下麵就來細說一下ASP.NET MVC Model驗證多種方式的實現。 一、瞭解什麼是ASP.NET MVC Model驗證 首先 ...
ASP.NET mvc的最好的優點之一就是支持Model驗證,這個特性很方便你可以選擇在定義Model的時候在欄位中採用特性進行註解約定,也可以在代碼中自己進行手動驗證。下麵就來細說一下ASP.NET MVC Model驗證多種方式的實現。
一、瞭解什麼是ASP.NET MVC Model驗證
首先,我們定義一個要用到的一個Model類,Appointment.cs:
1 using System; 2 using System.ComponentModel.DataAnnotations; 3 4 namespace ModelValidation.Models { 5 public class Appointment { 6 7 public string ClientName { get; set; } 8 9 [DataType(DataType.Date)] 10 public DateTime Date { get; set; } 11 12 public bool TermsAccepted { get; set; } 13 } 14 }
上面Appointment的欄位Date類型定義為日期類型,並用了System.ComponentModel.DataAnnotations命名空間來註解Model的欄位為日期類型,如果傳入不合法的日期Model就會驗證不合法。
再在Site.css中加入下麵的樣式用來標註錯誤的輸入項:
1 .input-validation-error { 2 border: 1px solid #f00; 3 background-color: #fee; 4 }
然後,創建一個視圖,MakeBooking.cshtml用來錄入信息:
1 @model ModelValidation.Models.Appointment 2 @{ 3 ViewBag.Title = "Make A Booking"; 4 } 5 <h4>Book an Appointment</h4> 6 7 @using (Html.BeginForm()) { 8 <p>Your name: @Html.EditorFor(m => m.ClientName)</p> 9 <p>Appointment Date: @Html.EditorFor(m => m.Date)</p> 10 <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p> 11 <input type="submit" value="Make Booking" /> 12 }
最後,在HomeController中加入下麵兩個Action:
public ViewResult MakeBooking() { return View(); } [HttpPost] public ViewResult MakeBooking(Appointment appt) { if (ModelState.IsValid) { return View("Completed", appt); } else { return View(); } }
我們查看/Home/MakeBooking會有下圖要效果:
這時我們看到Appointment Date輸入框為紅色的,表示輸入不合法。看看這個input要樣式class為:”input-validation-error text-box single-line“,而剛開始的時候為:”text-box single-line“正好多了一個”input-validation-error“,這也是剛開始我們為什麼要定義一個類名為”input-validation-error“的樣式的原因。換句話說,預設情況下當MVC的Model欄位驗證不通過的時候就會在輸入的頁面輸入項加上一個css類”input-validation-error“。
二、採用System.ComponentModel.DataAnnotations註解Model的欄位
上面我們演示了一個採用[DataType(DataType.Date)]來約定欄位必須為Date類型,DataType為枚舉類型,你可以選擇其中的任意類型來約定你的Model欄位。如下圖:
其實System.ComponentModel.DataAnnotations還為我們提供了其它很多驗證規則。比較常用的有:
[Required]:必填欄位
[RegularExpression("xx"):正則表達式
這些都是System.ComponentModel.DataAnnotations命名空間下定義好的類,下麵例舉出用於Model驗證的常用的類:
- CompareAttribute 提供比較兩個屬性的屬性。
- CreditCardAttribute 指定數據欄位值是信用卡號碼。
- CustomValidationAttribute 指定自定義的驗證方法來驗證屬性或類的實例。
- DataTypeAttribute 指定要與數據欄位關聯的附加類型的名稱。
- DisplayAttribute 提供一個通用特性,使您可以為實體分部類的類型和成員指定可本地化的字元串。
- EmailAddressAttribute 確認一電子郵件地址。
- MaxLengthAttribute 指定屬性中允許的數組或字元串數據的最大長度。
- MinLengthAttribute 指定屬性中允許的數組或字元串數據的最小長度。
- PhoneAttribute 使用電話號碼的正則表達式,指定數據欄位值是一個格式正確的電話號碼。
- RangeAttribute 指定數據欄位值的數值範圍約束。
- RegularExpressionAttribute 指定 ASP.NET 動態數據中的數據欄位值必須與指定的正則表達式匹配。
- RequiredAttribute 指定需要數據欄位值。
- UrlAttribute 提供 URL 驗證。
三、顯式手動驗證一個MVC的Model
除了上面結合Model定義時System.ComponentModel.DataAnnotations下的類來約定Model驗證規則這外,我們還可以在程式中手動驗證顯式手動驗證一個MVC的Model是否合法。下麵我們把Appointment之前加的DataAnnotations都去掉,代碼最終如下:
1 public class Appointment 2 { 3 public string ClientName { get; set; } 4 5 public DateTime Date { get; set; } 6 7 public bool TermsAccepted { get; set; } 8 }
這時,我們把接受輸入的Action MakeBooking改成手動判斷Model的欄位是否合法:
1 [HttpPost] 2 public ViewResult MakeBooking(Appointment appt) 3 { 4 5 if (string.IsNullOrEmpty(appt.ClientName)) 6 { 7 ModelState.AddModelError("ClientName", "Please enter your name"); 8 } 9 10 if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date) 11 { 12 ModelState.AddModelError("Date", "Please enter a date in the future"); 13 } 14 15 if (!appt.TermsAccepted) 16 { 17 ModelState.AddModelError("TermsAccepted", "You must accept the terms"); 18 } 19 20 if (ModelState.IsValid) 21 { 22 return View("Completed", appt); 23 } 24 else 25 { 26 return View(); 27 } 28 }
上面可以看到我們在Action方法的內部依次手動進行驗證相應的每個欄位的值是否滿足要求,如果驗證不通過就調用ModelState.AddModelError加入Model驗證錯誤信息,這個AddModelError有兩個參數,第一個為被驗證的欄位,第二個為要顯示錯誤信息提示的文本。驗證完了每個欄位之後調用ModelState.IsValid來總的判斷Model的驗證之後的結果是否合法。只要有一個欄位驗證沒通過或者我們調用了ModelState.AddModelError,ModelState.IsValid都會返回false。
四、在頁面顯示MVC的Model驗證錯誤信息
4.1、採用彙總的形式顯示MVC的Model驗證錯誤信息
我們在上面的例子中,當驗證不通過的時候我們除了把輸入框變紅之外,是沒有顯示文本提示的。其實要在頁面顯示MVC的Model驗證錯誤信息也很簡單,只需要在視圖中調用:@Html.ValidationSummary() 就可以了。
@model MVCModelBindingDemo.Models.Appointment @{ ViewBag.Title = "Make A Booking"; } <h4>Book an Appointment</h4> @using (Html.BeginForm()) { @Html.ValidationSummary() <p>Your name: @Html.EditorFor(m => m.ClientName)</p> <p>Appointment Date: @Html.EditorFor(m => m.Date)</p> <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p> <input type="submit" value="Make Booking" /> }
同樣我們在/Home/MakeBooking頁面中什麼都不錄入,直接提交將會出現下圖中的結果:
我們查看@Html.ValidationSummary()生成的html源碼如下圖:
生成的驗證錯誤信息用一個樣式名為"validation-summary-errors"的div,錯誤項是用ul 和li 列出。
下麵來介紹一下ValidationSummary()方法的幾種參數重載版本:
- Html.ValidationSummary():生成輸出所有驗證錯誤信息。
- Html.ValidationSummary(bool):如果bool為true,只顯示model-level錯誤信息,也就是通過ModelState.AddModelError來註冊的驗證信息。如果bool為false,生成輸出所有驗證錯誤信息。
- Html.ValidationSummary(string) :在生成輸出所有驗證錯誤信息之前顯示一段文字
Html.ValidationSummary(bool, string):在生成輸出驗證錯誤信息之前顯示一段文字,同樣bool為true,只顯示model-level錯誤信息。
4.2、分每個屬性(Property-Level )顯示驗證信息
除了採用上面彙總的形式顯示MVC的Model驗證錯誤信息,我們還可以分每個屬性(Property-Level )顯示驗證信息。Property-Level驗證信息是我們通過ModelState.AddModelError來註冊的驗證信息。下麵我們改一下/Home/MakeBooking視圖文件,改後的內容如下:
1 @model MVCModelBindingDemo.Models.Appointment 2 @{ 3 ViewBag.Title = "Make A Booking"; 4 } 5 <h4>Book an Appointment</h4> 6 7 @using (Html.BeginForm()) 8 { 9 <p>@Html.ValidationMessageFor(m => m.ClientName)</p> 10 <p>Your name: @Html.EditorFor(m => m.ClientName)</p> 11 <p>@Html.ValidationMessageFor(m => m.Date)</p> 12 <p>Appointment Date: @Html.EditorFor(m => m.Date)</p> 13 <p>@Html.ValidationMessageFor(m => m.TermsAccepted)</p> 14 <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p> 15 <input type="submit" value="Make Booking" /> 16 }
可以看到我們把@Html.ValidationSummary()去掉了,然後在每個欄位後面加入了@Html.ValidationMessageFor對應欄位的驗證信息。驗證效果如下圖: