public abstract class ModelValidatorProvider
{
public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ModelBindingExecutionContext context);
}
參數:
metadata:含驗證屬性的 Model 元資料。context:繫結執行上下文(含 ControllerContext)。核心邏輯:根據 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);
}
繼承 AssociatedValidatorProvider,實作 GetValidators(metadata, context, attributes):篩選 ValidationAttribute,透過靜態工廠字典建立 DataAnnotationsModelValidator 或適配器。另處理 IValidatableObject。
直接繼承 ModelValidatorProvider,GetValidators 邏輯:
metadata.ModelType 為數值型別(byte, short, int, long, float, double, decimal 等)→ 回傳 NumericModelValidator。DateTime → 回傳 DateModelValidator。ClientModelValidator 衍生類,僅產生客戶端規則,伺服器端 Validate 回傳空集合。缺點:錯誤訊息硬編碼於資源檔,無法自訂。
支援 IDataErrorInfo 介面:
ModelType 實作 IDataErrorInfo → 建立 DataErrorInfoClassModelValidator。ContainerType 實作 IDataErrorInfo → 建立 DataErrorInfoPropertyModelValidator。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 |
|---|---|
| 標準 DataAnnotations 驗證 | DataAnnotationsModelValidatorProvider(預設) |
| 需自訂客戶端數值/日期訊息 | 繼承 ClientDataTypeModelValidatorProvider 覆寫資源 |
| 既有 IDataErrorInfo 領域模型 | DataErrorInfoModelValidatorProvider(預設) |
| 多情境規則切換 | 繼承 DataAnnotationsModelValidatorProvider 擴充 |
ModelValidatorProvider 為驗證策略封裝,AssociatedValidatorProvider 統一屬性解析邏輯,三大內建 Provider 分別對應 DataAnnotations、ClientDataType、IDataErrorInfo。理解其分工與擴充點,可精準選擇或組合驗證機制。