首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET MVC 3 鏈式驗證擴展方法:結合 jQuery Validation 實現前端流暢驗證

     編輯:ASP.NET 基礎

背景與動機

MVC 3 預設採用 DataAnnotations 伺服端/客戶端驗證,但驗證規則分散在 Model 類別,View 中難以一眼看出欄位套用了哪些規則。本文示範**擴展方法 + 鏈式 API + jQuery Validation**,在 View 直接以流暢語法宣告驗證規則,並自動生成客戶端驗證腳本。

核心類別設計

namespace MvcWeb.Extensions
{
    // 1. JqueryHelper:擴展 WebViewPage,提供 .Jquery() 入口
    public class JqueryHelper
    {
        public ViewContext ViewContext { get; private set; }
        public WebViewPage ViewPage { get; private set; }
        public RouteCollection RouteCollection { get; private set; }
        public JqueryHelper(ViewContext vc, WebViewPage page, RouteCollection rc = null)
        {
            ViewContext = vc; ViewPage = page; RouteCollection = rc ?? RouteTable.Routes;
        }
    }

    public static class JqueryExtensions
    {
        public static JqueryHelper Jquery(this WebViewPage page)
        {
            var key = typeof(JqueryHelper);
            var helper = page.PageData[key] as JqueryHelper;
            if (helper == null) page.PageData[key] = helper = new JqueryHelper(page.ViewContext, page);
            return helper;
        }
    }

    // 2. JqueryValidations:收集規則與訊息,生成 jQuery Validation 設定腳本
    public class JqueryValidations
    {
        private readonly WebViewPage _page;
        private readonly Dictionary> _rules = new();
        private readonly Dictionary> _messages = new();

        public JqueryValidations(WebViewPage page) { _page = page; }

        // 鏈式規則方法
        public void Required(string name, string msg) => AddRule(name, "required", true, msg);
        public void Email(string name, string msg) => AddRule(name, "email", true, msg);
        public void Number(string name, string msg) => AddRule(name, "number", true, msg);
        public void Range(string name, int min, int max, string msg) => AddRule(name, "range", new[] { min, max }, msg);

        private void AddRule(string name, string rule, object value, string msg)
        {
            if (!_rules.ContainsKey(name)) _rules[name] = new Dictionary();
            _rules[name][rule] = value;
            if (!string.IsNullOrEmpty(msg))
            {
                if (!_messages.ContainsKey(name)) _messages[name] = new Dictionary();
                _messages[name][rule] = msg;
            }
        }

        // 元素級鏈式進入點
        public ValidationElement Element(string name) => new ValidationElement(name, this);

        // 生成腳本
        public string ToScripts(string formSelector)
        {
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            var sb = new StringBuilder();
            sb.Append("$("); serializer.Serialize(formSelector, sb); sb.Append(").validate(");
            serializer.Serialize(new { rules = _rules, messages = _messages, onkeyup = false }, sb);
            sb.Append(");");
            return sb.ToString();
        }
    }

    // 3. ValidationElement:提供 element.Required().Email()... 鏈式語法
    public class ValidationElement
    {
        public string Name { get; }
        public JqueryValidations Validations { get; }
        public ValidationElement(string name, JqueryValidations v) { Name = name; Validations = v; }
        public ValidationElement Required(string msg) { Validations.Required(Name, msg); return this; }
        public ValidationElement Email(string msg) { Validations.Email(Name, msg); return this; }
        public ValidationElement Number(string msg) { Validations.Number(Name, msg); return this; }
        public ValidationElement Range(int min, int max, string msg) { Validations.Range(Name, min, max, msg); return this; }
    }

    // 4. JqueryHelper 擴展:.Validations() 取得/建立驗證收集器
    public static class JQueryValidationExtensions
    {
        public static JqueryValidations Validations(this JqueryHelper helper, string name = "(default)")
        {
            var key = typeof(JqueryValidations) + "+" + name;
            var val = helper.ViewPage.PageData[key] as JqueryValidations;
            if (val == null) helper.ViewPage.PageData[key] = val = new JqueryValidations(helper.ViewPage);
            return val;
        }
    }
}

View 中使用 (Razor)

@using MvcWeb.Extensions
<!DOCTYPE html>
<html>
<head>
    <title>鏈式驗證 Demo</title>
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.js")"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.js")"></script>
</head>
<body>
    <form id="form" method="post">
        <input type="text" id="user.Name" name="user.Name" />
        @{ this.Jquery().Validations().Required("user.Name", "用戶名必填"); }

        <select name="user.Gender">
            <option value="">請選擇</option>
            <option value="1">男</option>
            <option value="2">女</option>
        </select>
        @{ this.Jquery().Validations().Required("user.Gender", null); }

        <input type="text" name="user.Email" />
        @{ this.Jquery().Validations().Element("user.Email").Required("Email必填").Email("格式錯誤"); }

        <input type="submit" value="提交" />
    </form>

    <script type="text/javascript">
        @Html.Raw(this.Jquery().Validations().ToScripts("#form"))
    </script>
</body>
</html>

關鍵設計亮點

設計效用
`PageData` 快取同一請求內多次呼叫 `.Validations()` 返回同一實例,規則自動合併
鏈式 `ValidationElement``Element("name").Required().Email().Range(...)` 可讀性極高
`JavaScriptSerializer` 序列化自動將規則字典轉為合法 JSON,避免手工拼接錯誤
`@Html.Raw` 輸出防止 Razor 自動 HTML 編碼導致腳本失效
擴展 `WebViewPage` 而非 `ViewPage`MVC 3 Razor 視圖基類為 `WebViewPage`,擴展正確類別才能在 View 中使用

注意事項

  1. **必須引用 `jquery.validate.js`**,否則生成的腳本無效。
  2. **驗證元素必須在 `
    ` 內**,jQuery Validation 只驗證表單內元素。
  3. **提交必須用 `` 或 `
  4. **規則順序**:雖鏈式順序不影響最終 JSON,但建議遵循業務邏輯順序 (必填 → 格式 → 範圍)。
  5. **IE9 相容性**:舊版 IE 可能 `onkeyup: false` 導致即時驗證異常,可移除或升級 jQuery Validation 版本。

現代化替代:Unobtrusive Validation (MVC 3 內建)

MVC 3 預設啟用 `jquery.validate.unobtrusive.js`,配合 Model `DataAnnotations` 自動生成 `data-val-*` 屬性,**零腳本即可完成客戶端驗證**。本文方案適用於:

  • 需在 View 動態決定驗證規則 (如權限控制、多語系訊息)。
  • 不想汙染 Model 屬性、追求 View 與驗證邏輯緊密綁定。
  • 學習擴展方法、鏈式 API、腳本生成機制。

總結

利用 **擴展方法擴展 `WebViewPage`**、**`PageData` 跨方法共享狀態**、**鏈式 `ValidationElement` 收集規則**、**`JavaScriptSerializer` 生成 JSON**,即可在 Razor View 中寫出 `this.Jquery().Validations().Element("email").Required().Email()` 這樣流暢、可讀、可維護的驗證宣告。這展示了 C# 擴展方法與動態語言特性結合的強大表達力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved