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

ASP.NET MVC ModelValidatorProvider 核心實作:AssociatedValidatorProvider 與三大內建 Provider

     編輯:關於ASP.NET

ModelValidatorProvider 抽象基類

public abstract class ModelValidatorProvider
{
    public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ModelBindingExecutionContext context);
}

參數:

  • metadata:含驗證屬性的 Model 元資料。
  • context:繫結執行上下文(含 ControllerContext)。

AssociatedValidatorProvider:屬性關聯式 Provider 基類

核心邏輯:根據 ModelMetadata 判斷是型別層級或屬性層級,取得對應 ICustomTypeDescriptor 解析屬性:

public abstract class AssociatedValidatorProvider : ModelValidatorProvider
{
    protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type);
    
    public sealed override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {
        IEnumerable<Attribute> attributes;
        if (metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName))
        {
            // 屬性層級
            var typeDescriptor = GetTypeDescriptor(metadata.ContainerType);
            var propDescriptor = typeDescriptor.GetProperties()[metadata.PropertyName];
            attributes = propDescriptor.Attributes.Cast<Attribute>();
        }
        else
        {
            // 型別層級
            var typeDescriptor = GetTypeDescriptor(metadata.ModelType);
            attributes = typeDescriptor.GetAttributes().Cast<Attribute>();
        }
        return GetValidators(metadata, context, attributes);
    }
    
    protected abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes);
}

DataAnnotationsModelValidatorProvider

繼承 AssociatedValidatorProvider,實作 GetValidators(metadata, context, attributes):篩選 ValidationAttribute,透過靜態工廠字典建立 DataAnnotationsModelValidator 或適配器。另處理 IValidatableObject。

ClientDataTypeModelValidatorProvider

直接繼承 ModelValidatorProvider,GetValidators 邏輯:

  • 若 metadata.ModelType 為數值型別(byte, short, int, long, float, double, decimal 等)→ 回傳 NumericModelValidator。
  • 若為 DateTime → 回傳 DateModelValidator。
  • 兩者皆為內部 ClientModelValidator 衍生類,僅產生客戶端規則,伺服器端 Validate 回傳空集合。

缺點:錯誤訊息硬編碼於資源檔,無法自訂。

DataErrorInfoModelValidatorProvider

支援 IDataErrorInfo 介面:

  • 型別層級:若 ModelType 實作 IDataErrorInfo → 建立 DataErrorInfoClassModelValidator。
  • 屬性層級:若 ContainerType 實作 IDataErrorInfo → 建立 DataErrorInfoPropertyModelValidator。

IDataErrorInfo 實作範例

public class Contact : IDataErrorInfo
{
    public string Error => "無效聯系人!";
    
    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "Name": return "姓名是必需的!";
                case "PhoneNo": return "電話號碼格式錯誤!";
                case "EmailAdderss": return "無效的電子郵箱地址!";
                default: return null;
            }
        }
    }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
    public string EmailAdderss { get; set; }
}

Provider 選擇指南

情境建議 Provider
標準 DataAnnotations 驗證DataAnnotationsModelValidatorProvider(預設)
需自訂客戶端數值/日期訊息繼承 ClientDataTypeModelValidatorProvider 覆寫資源
既有 IDataErrorInfo 領域模型DataErrorInfoModelValidatorProvider(預設)
多情境規則切換繼承 DataAnnotationsModelValidatorProvider 擴充

總結

ModelValidatorProvider 為驗證策略封裝,AssociatedValidatorProvider 統一屬性解析邏輯,三大內建 Provider 分別對應 DataAnnotations、ClientDataType、IDataErrorInfo。理解其分工與擴充點,可精準選擇或組合驗證機制。

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