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

ASP.NET MVC 表單驗證框架打造實戰 (一):從手動驗證到屬性驅動

     編輯:關於ASP.NET

Web 開發中表單驗證不可或缺。ASP.NET MVC 早期無內建驗證屬性 (DataAnnotations 尚未普及),本文從手動 if (int.TryParse...) 起步,逐步引入 Attribute、反射、ModelBinder 概念,打造輕量驗證框架雛形。

痛點:手動驗證碎片化


if (!int.TryParse(Request.Form["age"], out int age)) { /* 錯誤 */ }
if (age < 0 || age > 150) { /* 錯誤 */ }
// 每個欄位重複、易漏、難維護

第一步:定義驗證屬性


[AttributeUsage(AttributeTargets.Property)]
public class RangeAttribute : Attribute
{
    public int Min { get; set; }
    public int Max { get; set; }
    public string Message { get; set; }
    public RangeAttribute(int min, int max, string message)
    {
        Min = min; Max = max; Message = message;
    }
}

[AttributeUsage(AttributeTargets.Property)]
public class RequiredAttribute : Attribute
{
    public string Message { get; set; }
    public RequiredAttribute(string message) { Message = message; }
}

第二步:實體標註屬性


public class Student
{
    [Range(0, 100, "分數需在 0-100")]
    public int Score { get; set; }

    [Required("姓名必填")]
    public string Name { get; set; }
}

第三步:實體驗證方法 (反射掃描屬性)


public class ValidatableBase
{
    public bool Validate(out List errors)
    {
        errors = new List();
        foreach (var prop in GetType().GetProperties())
        {
            var val = prop.GetValue(this);
            // Range
            var rangeAttr = prop.GetCustomAttributes(typeof(RangeAttribute), true).FirstOrDefault() as RangeAttribute;
            if (rangeAttr != null && val is int iv)
            {
                if (iv < rangeAttr.Min || iv > rangeAttr.Max)
                    errors.Add(rangeAttr.Message);
            }
            // Required
            var reqAttr = prop.GetCustomAttributes(typeof(RequiredAttribute), true).FirstOrDefault() as RequiredAttribute;
            if (reqAttr != null)
            {
                if (val == null || (val is string s && string.IsNullOrWhiteSpace(s)))
                    errors.Add(reqAttr.Message);
            }
        }
        return errors.Count == 0;
    }
}

public class Student : ValidatableBase { /* 屬性定義 */ }

第四步:整合 ModelBinder (概念)

ASP.NET MVC DefaultModelBinder 綁定完成後,可呼叫 model.Validate(out errors),將錯誤加入 ModelState,View 自動顯示 ValidationMessageFor。

測試驗證


[TestMethod]
public void Student_Validate_Fail()
{
    var s = new Student { Score = -1, Name = "" };
    var ok = s.Validate(out var errors);
    Assert.IsFalse(ok);
    Assert.AreEqual(2, errors.Count);
}

下一步預告

下篇將解決 Validate 方法膨脹、驗證邏輯硬編碼問題:引入 IValidator 介面,讓屬性自我驗證,實現開放封閉原則。

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