[VS2010] ASP.NET MVC 2.0 新功能:資料塑模驗證 (Model Validation)
Model Validation 是在 ASP.NET MVC 2.0 加入的新功能,以往 ASP.NET Web Form 乃至 ASP.NET MVC 1.0 要對 Model 做資料驗證的時候,總是要寫一大堆的 Validation 程式碼,還分 Server-side validation 和 Client-side validation 兩種,筆者想大多數的開發人員可能都煩了,因為拉驗證控制項是很費工的事,欄位一多的話真的會拉到死人(尤其是數十個欄位那種),而且若要處理欄位間的變化驗證也很麻煩,隨著 jQuery 的出現,已經有一些 Form Plug-ins 可以透過 JavaScript 解決此問題,但 Server-side 驗證仍然沒有解決,適才 .NET Framework 3.5 SP1 中新增的 ASP.NET Dynamic Data Framework 又將資料驗證簡化成只要使用宣告的方式就解決了,對於 ASP.NET MVC 開發人員來說真的會流口水 … 還好,ASP.NET 4.0 中的 MVC 2.0 把這個功能拉了過來,也就是本文的 Model Validation 功能。
我們可以用 Visual Studio 2010 新建一個 ASP.NET MVC 2.0 專案:
然後做到這樣的功能:
現在我們就來看看怎麼做吧:
1. 實作一個 MVC Controller:
首先,我們先定義這樣的一個資料類別:
眼尖的讀者應該會發現,這個類別只是一個簡單的 POCO (Plain-Old-CLR-Object) 類別物件,它在這個案例中作為資料來源,而剛好的是 Entity Framework 2.0 也支援使用 POCO 來存取資料庫的能力。
接著,我們加入一個 FriendController,作為 MVC 的控制介面:
然後我們可以利用這個 Controller 來建立一個新的 View,資料類別來選擇前面所建的 POCO 類別:
接著,編輯 View 網頁,將資料項加入網頁中,在這裡使用的是 ASP.NET MVC 2.0 新增的 strong-typed HTML Helper:
目前版本的程式執行起來畫面如下:
但因為目前沒有加入任何的資料驗證能力,因此如果輸入了錯誤的資料,伺服器端是不會擋的。
2. 使用資料記號來建立資料驗證功能:
資料記號 (Data Annotation) 是發源自 ASP.NET Dynamic Data Framework 的功能,它最大的好處就是只要用加入宣告的方式,就可以針對資料欄位做限制以及範圍限定的處理,這點可以大大的簡化開發人員在處理資料驗證與格式限制所要花費的工作與工時,它在 ASP.NET Dynamic Data Framework 的作法是這樣的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(CustomerMetadata))]
public partial class Customer
{
partial void OnValidate(System.Data.Linq.ChangeAction action)
{
if (!char.IsUpper(this._LastName[0]) ||
!char.IsUpper(this._FirstName[0]) ||
!char.IsUpper(this._Title[0]))
throw new ValidationException(
"Data value must start with an uppercase letter.");
}
}
public class CustomerMetadata
{
[Required()]
public object Title;
}
只是在 ASP.NET Dynamic Data Framework 的實作版本還不夠成熟,當時未將它導入 ASP.NET MVC 以及 Web Form Framework 中,到了 ASP.NET 4.0,MVC 2.0 以及 Web Form 都可以利用 Data Annotation 來處理資料驗證的功能,對開發人員來說真是一大褔音。在 ASP.NET MVC 2.0 中,支援四種內建的 Data Annotation:[Required], [StringLength], [Range], [RegularExpression],只要引用 System.ComponentModel.DataAnnotations 命名空間即可使用。我們可以在 Person 資料類別中對各項欄位加入必要的限制與驗證屬性:
接著,為了要讓在 Data Annotation 中的錯誤訊息 (Error Message) 可以順利的出現在驗證失敗的欄位中,我們可以在 View 中加入 Html.ValidationMessageFor() 這個 strong-typed HTML Helper 指令來做到:
而程式的執行結果如下:
現在 Server 端的驗證已經完成,但是筆者認為大家還是比較喜歡用 Client-side Validation,可以節省來回時間,所以我們再接著做。
3. 在 MVC 2.0 的 Model Validation 中加入用戶端驗證行為。
MVC 2.0 要將 Model Validation 加入 View 網頁中真的是超級簡單,因為只要加入 MicrosoftAjax.js 以及 MicrosoftMvcValidation.js,並且在 View 的表單之前,使用 Html.EnableClientValidation() 啟用用戶端驗證即可。
執行結果如下(不會再出現 round-trip 的 PostBack):
若不想使用內建的 Ajax 函式庫,也可以自行選用 jQuery 的 Form plug-in,並利用 jQuery 的 AJAX 功能來實作。
4. 在 Data Annotation 中使用自訂的資料驗證功能
在前面的步驟中,我們已經實作出完整的驗證功能,但目前還有一個問題,就是若想要實作自訂驗證的行為(例如身份證字號格式,Email 格式與信用卡格式等),則可以利用延展 DataAnnotations 命名空間中的類別來做到,例如我們可以延展 Email 格式驗證的功能:
我們就可以在 Model 的程式碼中直接使用這個行為:
本程式的執行結果是:
5. 將 POCO 物件與資料庫連結。
現在,我們只剩下一個工作,就是將資料存到資料庫中:
筆者在之前有介紹過如何利用 POCO 物件連接 Entity Framework 2.0 Data Model,我們還可以利用 Entity Framework 2.0 中的 Model-First 功能來預先定義出資料表的結構,然後與 POCO 連接:
在 Model-First 的行為中,Entity Framework 的 Entity Data Model Designer 會產生一個 Person 的類別,這樣會和我們原本的 POCO 類別衝突,因此我們對 POCO 物件做一點處理:
利用 MetadataType 將 Data Annotation 驗證行為導向到原本的 Person POCO 物件,並將原本的 POCO 物件更名,如此即可避開衝突的問題。
6. 將資料儲存到資料庫中。
最後,我們只要將 Model 儲存到資料庫中即可,語法也是簡單到不行:
現在,我們可以用 Friends/Create URL 來加入新的資料到 Friend 資料庫中了。
參考資料:
ASP.NET Dynamic Data’s Data Annotation
Models and Validations in ASP.NET MVC
圖片來源:http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx