Model驗證
上節說了Asp.net MVC中Model的綁定,本節講解下Model綁定時的數據驗證。
數據結構
Model驗證中的錯誤信息怎樣存儲?怎樣傳遞給View
?
ModelError
類型每條錯誤信息,ModelErrorCollection
錯誤提示的集合,ModelState
為存儲錯誤驗證和數據源。其在參數綁定時將生成的ModelState
(驗證信息和數據源)保存到了Controller
的ModelState
屬性中(為ViewData
的一部分,類型為ModelStateDictionary
)。
[Serializable] public class ModelState { private ModelErrorCollection _errors = new ModelErrorCollection(); public ValueProviderResult Value { get; set; } public ModelErrorCollection Errors { get { return _errors; } } }
手工數據驗證
了解驗證數據傳遞到View
的機制,可手工寫數據驗證方法.添加錯誤信息ModelState.AddModelError(key,value)
可驗類型
手工實現是麻煩的,可用通過定制數據,使數據可使用相應的驗證機制ModelValidator
驗證。
- 實現抽象類
ValidationAttribute
,將特性綁定到需要驗證的數據上
- 實現接口
IValidatableObject
- 實現接口
IDataErrorInfo
驗證驗證
對Model的驗證為ModelValidator
,可通過實現該抽象類實現自定義的驗證策略。ModelValidator
的抽象方法為Validate
.
數據類型 | 驗證方法 | validatorProvider |
---|---|---|
ValidationAttribute | DataAnnotationsModelValidator | DataAnnotationsModelValidatorProvider |
IValidatableObject | ValidatableObjectAdapter | DataAnnotationsModelValidatorProvider |
IDataErrorInfo | DataErrorInfoModelValidator | DataErrorInfoModelValidatorProvider |
跟IValueProvider
數據提供機制相似,這裏有ModelValidatorProvider
ModelValidator
提供器。可以通過ModelValidatorProviders
註冊數據驗證機制。
CompositeModelValidator執行驗證的組織
CompositeModelValidator
為ModelValidator
的內部類,通過靜態方法GetModelValidator
獲得。
CompositeModelValidator
的Validate
會根據數據的元數據驗證其屬性Metadata.PropertiesAsArray
。其中ModelMetadata
的GetValidators
方法會得到其上的所有驗證,註意 ModelValidatorProvider
有抽象方法public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context);
即可以通過ModelMetadata
可獲得對應的驗證機制
public class ModelMetadata{
public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context)
{
return ModelValidatorProviders.Providers.GetValidators(this, context);
}
}
public static class ModelValidatorProviders
{
public static ModelValidatorProviderCollection Providers
{
get { return _providers; }
}
}
驗證策略
數據綁定時驗證,其實驗證註意驗證的為復雜類型。
在DefaultModelBinder
進行BindModel
時驗證並將驗證信息保存到ModelState
.
OnModelUpdated(controllerContext, newBindingContext);
方法
Model驗證