之前我們一直討論的Model驗證僅限於服務端驗證,即在Web服務器根據相應的規則對請求數據實施驗證。如果我們能夠在客戶端(浏覽器)對用戶輸入的數據先進行驗證,這樣會減少針對服務器請求的頻率,從而緩解Web服務器訪問的壓力。ASP.MVC 2.0及其之前的版本采用ASP.NET Ajax進行客戶端驗證,在ASP.NET MVC 3.0中,jQuery驗證框架被引入是我們可以采用Unobtrusive JavaScript的方式進行客戶端驗證。
一、Unobtrusive JavaScript
Unobtrusive JavaScript已經成為了JavaSccript編程的一個指導方針,Unobtrusive JavaScript體現了一種主流的Web設計策略,即“漸進式增強(PE,Progressive Enhancement)”。它采用分層的方式實現了Web頁面內容與功能的分離,即用於實現某種功能的JavaScript不是內嵌於用於展現內容的HTML中,而是作為獨立的層次建立在HTML之上。
我們就以驗證為例,一個Web頁面中具有一個表單,我們需要 對針對表單中三個文本框(foo、bar和baz)的輸入進行驗證。假設具體的驗證操作實現在validate函數中,那麼我們可以采用如下的HTML時相應的文本框在失去焦點的時候對輸入的數據實施驗證。
1: <form action="/">
2: <input id="foo" type="text" onblur="validate()" />
3: <input id="bar" type="text" onblur="validate()" />
4: <input id="baz" type="text" onblur="validate()" />
5: ...
6: </form>
但這不是一個好的設計,理想的方式是讓HTML只用於定義內容呈現的結構,讓CSS控制內容呈現的樣式,而所有功能的實現定義在JavaScript中,所以用於實現驗證對JavaScript的調用不應該出現在HTML中。所以按照Unobtrusive JavaScript的編程方式,我們應該將以內聯方式實現的事件注冊(onblur="validate()")替換成如下的形式。
1: <form action="/">
2: <input id="foo" type="text"/>
3: <input id="bar" type="text"/>
4: <input id="baz" type="text" />
5: </form>
6:
7: <script type="text/javascript">
1:
2: window.onload = function () {
3: document.getElementById("foo").onblur = validate;
4: document.getElementById("bar").onblur = validate;
5: document.getElementById("baz").onblur = validate;
6: } </script>
Unobtrusive JavaScript是一個很寬泛的話題,在本篇中不可能展開進行系統地介紹。Unobtrusive JavaScript在jQuery的驗證中得到了很好的體現,接下來我們就簡單地介紹一下使用jQuery進行驗證的編程方式。
二、以內聯的方式指定驗證規則
jQuery的驗證實際上是對存在於表單的輸入元素進行驗證,它支持一種內聯(Inline)的編程方式是我們可以直接將驗證的規則直接編寫在被驗證輸入HTML元素的class(表示CSS類型)屬性中。考慮到有一些讀者對jQuery的驗證框架可能不太熟悉,為此我們來做一個簡單的實例驗證。
雖然演示jQuery驗證使用一個單純的HTML文件就可以了,但是在這裡我們還是通過Visual Studio的ASP.NET MVC項目模板創建一個空的Web應用,這樣做有兩個目的:其一、項目在創建過程中會自動添加包含jQuery本身及其驗證插件的.js文件;其二,可以確保我們現在使用的用於驗證的.js文件和ASP.NET MVC真正使用的.js文件是一致的。我們創建如下一個默認的HomeController,在Action方法Index中將默認的View呈現出來。
1: public class HomeController : Controller
2: {
3: public ActionResult Index()
4: {
5: return View(new Contact());
6: }
7: }
我們將作為呈現Web頁面的整個HTML定義在Action方法對應的View中,如下所示的代碼片斷是該View的定義。由於我們使用View來定義最終呈現的完整的HTML,所以我們將Layout設置為Null。
1: @{
2: Layout = null;
3: }
4: <!DOCTYPE html>
5: <html>
6: <head>
7: <link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" rel="stylesheet" type="text/css" />
8: <script type="text/javascript" src="http://www.cnblogs.com/Scripts/jquery-1.6.2.js">
</script>
1:
2: <script type="text/javascript" src="http://www.cnblogs.com/Scripts/jquery.validate.js"/>
3: <script type="text/javascript">
4: $(document).ready(function () {
5: $("form").validate();
6: $("td:first-child").css("text-align", "right");
7: });
8: </script>
9: <style type="text/css">
10: label.error{color: red;}
11: </style>
12: <title>Index</title>
13: </head>
14: <body>
15: <form action="/">
16: <table>
17: <tr>
18: <td>姓名:</td>
19: <td><input class="required" id="name" name="name" type="text"/></td>
20: </tr>
21: <tr>
22: <td>出生日期:</td>
23: <td><input class="required date" id="birhthDate" name="birhthDate" type="text"/></td>
24: </tr>
25: <tr>
26: <td>Blog地址:</td>
27: <td><input class="required url" id="blogAddress" name="blogAddress" type="text"/></td>
28: </tr>
29: <tr>
30: <td>Email地址:</td>
31: <td><input class="required email" id="emailAddress" name="emailAddress" type="text"/></td>
32: </tr>
33: <tr>
34: <td colspan="2"><input type="submit" value="保存" /></td>
35: </tr>
36: </table>
37: </form>
38: </body>
39: </html>