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

ASP.NET MVC 表單驗證框架打造實戰 (二):屬性驗證邏輯內聚與介面解耦

     編輯:關於ASP.NET

承上篇,解決驗證屬性邏輯膨脹、擴充困難問題。引入 IValidator 介面,讓每個驗證屬性 (RangeAttribute、RequiredAttribute) 實作自身驗證邏輯,實體 Validate() 僅遍歷屬性並委派驗證,符合單一職責與開放封閉原則。

核心介面

public interface IValidator
{
    bool Validate(object value, out string errorMessage);
}

屬性實作 IValidator

RangeAttribute


[AttributeUsage(AttributeTargets.Property)]
public class RangeAttribute : Attribute, IValidator
{
    public int Min { get; set; }
    public int Max { get; set; }
    public string ErrorMessage { get; set; }

    public RangeAttribute(int min, int max, string errorMessage)
    {
        Min = min; Max = max; ErrorMessage = errorMessage;
    }

    public bool Validate(object value, out string errorMessage)
    {
        errorMessage = null;
        if (value is int val)
        {
            if (val < Min || val > Max)
            {
                errorMessage = ErrorMessage;
                return false;
            }
        }
        return true;
    }
}

RequiredAttribute


[AttributeUsage(AttributeTargets.Property)]
public class RequiredAttribute : Attribute, IValidator
{
    public string ErrorMessage { get; set; }

    public bool Validate(object value, out string errorMessage)
    {
        errorMessage = null;
        if (value == null || (value is string s && string.IsNullOrWhiteSpace(s)))
        {
            errorMessage = ErrorMessage;
            return false;
        }
        return true;
    }
}

實體驗證方法


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

    [Required(ErrorMessage = "姓名不可為空")]
    public string Name { get; set; }

    public bool Validate(out List errors)
    {
        errors = new List();
        var props = GetType().GetProperties();
        foreach (var prop in props)
        {
            var validators = prop.GetCustomAttributes(typeof(IValidator), true).Cast();
            foreach (var v in validators)
            {
                if (!v.Validate(prop.GetValue(this), out string err))
                    errors.Add(err);
            }
        }
        return errors.Count == 0;
    }
}

測試驗證


[TestMethod]
public void Student_Validation_Fails_On_Invalid_Score()
{
    var s = new Student { Score = -1, Name = "Tom" };
    var ok = s.Validate(out var errors);
    Assert.IsFalse(ok);
    Assert.IsTrue(errors.Contains("分數必須在 0-100 之間"));
}

優勢總結

  • 單一職責:每個屬性只管自己的驗證規則。
  • 開放封閉:新增驗證類型 (如 RegexAttribute) 只需實作 IValidator,不修改實體 Validate。
  • 可測試:屬性驗證邏輯可獨立單元測試。
  • 整合 ModelBinder:ASP.NET MVC 模型繫結器可自動呼叫 Validate 並將錯誤加入 ModelState。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved