public abstract class ModelValidator
{
public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules();
public abstract IEnumerable<ModelValidationResult> Validate(object container);
public virtual bool IsRequired { get; }
}
Validate(container):核心驗證邏輯,container 為被驗證物件(屬性驗證時為父物件)。回傳 ModelValidationResult 集合,成功時回傳空或 null。ModelValidationResult:MemberName(欄位名稱)+ Message(錯誤訊息)。頂層驗證 MemberName = String.Empty。GetClientValidationRules():產生前端驗證規則(Unobtrusive JavaScript 用)。IsRequired:標示是否為必填驗證,供前端 required 規則判斷。封裝 ValidationAttribute,前文已詳細剖析。優服務端驗證呼叫 Attribute.GetValidationResult,客戶端規則由適配器產生。
基類:internal class ClientModelValidator : ModelValidator,僅支援客戶端驗證。
public ClientModelValidator(ModelMetadata metadata, ControllerContext context, string validationType, string errorMessage);
public sealed override IEnumerable<ModelClientValidationRule> GetClientValidationRules();
public sealed override IEnumerable<ModelValidationResult> Validate(object container) => Enumerable.Empty<ModelValidationResult>();
validationType 對應 jQuery Validate 規則名稱(如 number、date)。
internal sealed class NumericModelValidator : ClientModelValidator
{
public NumericModelValidator(ModelMetadata metadata, ControllerContext context)
: base(metadata, context, "number", ClientDataTypeModelValidatorProvider.GetFieldMustBeNumericResource(context)) { }
}
internal sealed class DateModelValidator : ClientModelValidator
{
public DateModelValidator(ModelMetadata metadata, ControllerContext context)
: base(metadata, context, "date", ClientDataTypeModelValidatorProvider.GetFieldMustBeDateResource(context)) { }
}
由 ClientDataTypeModelValidatorProvider 針對數值/DateTime 型別自動建立。
DataErrorInfoClassModelValidator:型別層級,呼叫 IDataErrorInfo.Error 取得整體錯誤。DataErrorInfoPropertyModelValidator:屬性層級,呼叫 IDataErrorInfo[columnName] 取得屬性錯誤。由 DataErrorInfoModelValidatorProvider 建立。
null 或空集合(Enumerable.Empty<ModelValidationResult>())。ModelValidationResult 的集合。ValidationResult.Success 實為 null,可直接比較。public class CustomModelValidator : ModelValidator
{
public CustomModelValidator(ModelMetadata metadata, ControllerContext context) : base(metadata, context) { }
public override IEnumerable<ModelValidationResult> Validate(object container)
{
var value = Metadata.Model;
if (value == null || String.IsNullOrWhiteSpace(value.ToString()))
yield return new ModelValidationResult { MemberName = Metadata.PropertyName, Message = "自訂錯誤:不可為空白" };
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
yield return new ModelClientValidationRule { ValidationType = "custom", ErrorMessage = "自訂錯誤:不可為空白" };
}
}
ModelValidator 為驗證執行單元,四大內建實作分別對應 DataAnnotations、客戶端型別驗證、IDataErrorInfo。掌握其介面契約與回傳慣例,可輕鬆實作自訂驗證邏輯並整合前後端。