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

ASP.NET MVC DataAnnotationsModelValidator 運作原理與適配器體系

     編輯:關於ASP.NET

DataAnnotationsModelValidator 核心職責

封裝 ValidationAttribute,實作 ModelValidator 介面,提供伺服器端驗證邏輯與客戶端規則產生。

類別結構與關鍵成員

public class DataAnnotationsModelValidator : ModelValidator
{
    public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
    
    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules();
    
    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        var validationContext = new ValidationContext(container ?? this.Metadata.Model, null, null)
        {
            DisplayName = this.Metadata.GetDisplayName()
        };
        var validationResult = this.Attribute.GetValidationResult(this.Metadata.Model, validationContext);
        if (validationResult != ValidationResult.Success)
        {
            yield return new ModelValidationResult { Message = validationResult.ErrorMessage };
        }
    }
    
    protected ValidationAttribute Attribute { get; }
    protected string ErrorMessage { get; } // 來源於 Attribute.FormatErrorMessage(Metadata.DisplayName)
    public override bool IsRequired { get; } // 僅 RequiredAttribute 回傳 true
}

Validate 方法詳解

  1. 建立 ValidationContext,被驗證物件為 container 或 Metadata.Model,顯示名稱取自 Metadata.DisplayName。
  2. 呼叫封裝屬性的 GetValidationResult(model, context)。
  3. 若驗證失敗(非 ValidationResult.Success),包裝成 ModelValidationResult 回傳;成功則回傳空列舉。

輔助屬性邏輯

  • ErrorMessage:呼叫 Attribute.FormatErrorMessage(Metadata.DisplayName) 格式化錯誤訊息。
  • IsRequired:僅當封裝屬性為 RequiredAttribute 時回傳 true,供前端 required 規則判斷。

泛型適配器:DataAnnotationsModelValidator<TAttribute>

public class DataAnnotationsModelValidator<TAttribute> : DataAnnotationsModelValidator where TAttribute : ValidationAttribute
{
    public DataAnnotationsModelValidator(ModelMetadata metadata, ModelBindingExecutionContext context, TAttribute attribute);
    protected TAttribute Attribute { get; } // 強型別屬性存取
}

內建四大專用適配器

針對常用屬性提供強型別適配器,主要差異在覆寫 GetClientValidationRules 產生對應前端規則:

適配器對應屬性前端規則類型關鍵參數
RequiredAttributeAdapterRequiredAttributerequired無
RangeAttributeAdapterRangeAttributerangemin, max
RegularExpressionAttributeAdapterRegularExpressionAttributeregexpattern
StringLengthAttributeAdapterStringLengthAttributelengthmax

自訂屬性整合範例

public class AgeRangeAttribute : RangeAttribute, IClientValidatable
{
    public AgeRangeAttribute(int min, int max) : base(min, max) { }
    
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ValidationType = "agerange",
            ErrorMessage = FormatErrorMessage(metadata.DisplayName)
        };
    }
}

public class AgeRangeAttributeAdapter : DataAnnotationsModelValidator<AgeRangeAttribute>
{
    public AgeRangeAttributeAdapter(ModelMetadata metadata, ControllerContext context, AgeRangeAttribute attribute) 
        : base(metadata, context, attribute) { }
    
    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        yield return new ModelClientValidationRule
        {
            ValidationType = "agerange",
            ErrorMessage = Attribute.FormatErrorMessage(Metadata.DisplayName)
        };
    }
}

// 註冊
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(AgeRangeAttribute), typeof(AgeRangeAttributeAdapter));

總結

DataAnnotationsModelValidator 為驗證屬性與 MVC 驗證管線的橋樑,基類處理伺服器端驗證共通邏輯,泛型子類與四大專用適配器提供強型別存取與客戶端規則產生。自訂屬性只需實作 IClientValidatable 並註冊對應適配器即可無縫整合。

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