Model验证

上节说了Asp.net MVC中Model的绑定,本节讲解下Model绑定时的数据验证。

数据结构

Model验证中的错误信息怎样存储?怎样传递给View?
ModelError类型每条错误信息,ModelErrorCollection错误提示的集合,ModelState为存储错误验证和数据源。其在参数绑定时将生成的ModelState(验证信息和数据源)保存到了ControllerModelState属性中(为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执行验证的组织

CompositeModelValidatorModelValidator的内部类,通过静态方法GetModelValidator获得。
CompositeModelValidatorValidate会根据数据的元数据验证其属性Metadata.PropertiesAsArray。其中ModelMetadataGetValidators方法会得到其上的所有验证,注意 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);方法

原文地址:https://www.cnblogs.com/LoveTomato/p/9550135.html