好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelVali

ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider

DataAnnotationsModelValidator最终是通过它对应的ModelValidatorProvider,即DataAnnotationsModelValidatorProvider创建的。通过前面的介绍我们知道它是AssociatedValidatorProvider的子类,后者在用于获取ModelValidator的GetValidators方法中已经根据指定的Model元数据所有特性创建出来,DataAnnotationsModelValidator只需要 从中筛选出继承自ValiationAttribute的验证特性并创建对象的DataAnnotationsModelValidator就可以了 。[本文已经同步到《 How ASP.NET MVC Works? 》中]

目录 
DataAnnotationsModelValidator 
基于ValidationAttribute的ModelValidator的创建 
基于IValidatableObject的ModelValidator的创建 
默认的ModelValidator创建机制 
对ModelValidator创建方式的定制

DataAnnotationsModelValidator

我们现在结合DataAnnotationsModelValidator的相关定义来讨论一下具体的ModelValidator提供机制。如下面的代码片断所示,DataAnnotationsModelValidatorProvider具有两个静态的字段AttributeFactories和DefaultAttributeFactory,后者是一个DataAnnotationsModelValidationFactory委托,前者是以此委托为Value以Type对象为Key的字典。

    1:   public   class  DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
    2:  {
    3:       //其他成员 
    4:       internal   static   readonly  Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories;
    5:       internal   static  DataAnnotationsModelValidationFactory DefaultAttributeFactory;
    6:   
    7:       internal   static  DataAnnotationsValidatableObjectAdapterFactory DefaultValidatableFactory;
    8:       internal   static   readonly  Dictionary<Type, DataAnnotationsValidatableObjectAdapterFactory> ValidatableFactories;
    9:      
   10:       protected   override  IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, HttpActionContext actionContext, IEnumerable<Attribute> attributes);
   11:  }
   12:   
   13:   public   delegate  ModelValidator DataAnnotationsModelValidationFactory(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
   14:   
   15:   public   delegate  ModelValidator DataAnnotationsValidatableObjectAdapterFactory(ModelMetadata metadata, ControllerContext context);

基于ValidationAttribute的ModelValidator的创建

委托 DataAnnotationsModelValidationFactory 根据ModelMetadata、ControllerContext和ValidationAttribute返回一个ModelValidator对象,而字段AttributeFactories表示的字典对象的Key是具体的验证特性的类型,也就是说它维护一个ValidationAttribute特性类型和对应ModelValidator工厂的匹配关系。在重写的GetValidators方法中, 针对指定的每一个ValidationAttribute,它先根据其类型从AttributeFactories中获取一个对应的DataAnnotationsModelValidationFactory委托,如果该委托存在,则用它来创建相应的ModelValidator对象;否则就采用字段DefaultAttributeFactory表示的DataAnnotationsModelValidationFactory委托来进行ModelValidator的创建 。

基于IValidatableObject的ModelValidator的创建

除了AttributeFactories和DefaultAttributeFactory,DataAnnotationsModelValidatorProvider还具有 DefaultValidatableFactory 和ValidatableFactories这两个静态属性,它们用于针对可验证对象(实现了IValidatableObject接口)的ModelValidator的创建。DataAnnotationsModelValidator的类型是另外一个类型为 DataAnnotationsValidatableObjectAdapterFactory 的委托,该委托根据ModelMetadata和ControllerContext创建相应的ModelValidator。ValidatableFactories是一个以此委托为Value,以Type对象为Key的字典。

当DataAnnotationsModelValidatorProvider完成了针对基于验证特性的ModelValidator的创建之后,如果 根据Model元数据解析出来的Model类型实现了IValidatableObject接口,那么先从字典ValidatableFactories中根据此类型获取一个对应的DataAnnotationsValidatableObjectAdapterFactory委托,如果匹配的委托对象存在,则用其进行ModelValidator的创建;否则采用通过字段DefaultValidatableFactory表示的默认工厂来创建相应的ModelValidator对象 。

默认的ModelValidator创建机制

在DataAnnotationsModelValidatorProvider类型被加载的时候,上述的四个字段会在静态构造函数调用时被初始化。从如下的代码片断可看出,对于一般的ValidationAttribute,对应的ModelValidator是一个 DataAnnotationsModelValidator 对象(DefaultAttributeFactory字段);针对RangeAttribute、RegularExpressionAttribute 、RequiredAttribute和StringLengthAttribute这四种验证特性,它们对应的 适配ModelValidator 会被创建出来。而对于可验证对象来说,默认情况下提供的ModelValidator列表中还包含一个 ValidatableObjectAdapter 对象。

    1:   public   class  DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
    2:  {
    3:       //其他成员 
    4:       static  DataAnnotationsModelValidatorProvider()
    5:      {
    6:           //1、DefaultAttributeFactory 
    7:          DefaultAttributeFactory = (metadata, context, attribute) =>  new  DataAnnotationsModelValidator(metadata, context, attribute);
    8:   
    9:           //2、AttributeFactories 
   10:          Dictionary<Type, DataAnnotationsModelValidationFactory> dictionary =  new  Dictionary<Type, DataAnnotationsModelValidationFactory>();
   11:          dictionary.Add( typeof (RangeAttribute), (metadata, context, attribute) =>  new  RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute));
   12:          dictionary.Add( typeof (RegularExpressionAttribute), (metadata, context, attribute) =>  new  RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute));
   13:          dictionary.Add( typeof (RequiredAttribute), (metadata, context, attribute) =>  new  RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute));
   14:          dictionary.Add( typeof (StringLengthAttribute), (metadata, context, attribute) =>  new  StringLengthAttributeAdapter(metadata, context,(StringLengthAttribute)attribute));
   15:          AttributeFactories = dictionary;
   16:   
   17:           //3、DefaultValidatableFactory 
   18:          DefaultValidatableFactory = (metadata, context) =>  new  ValidatableObjectAdapter(metadata, context);
   19:   
   20:           //4、ValidatableFactories 
   21:          ValidatableFactories =  new  Dictionary<Type, DataAnnotationsValidatableObjectAdapterFactory>();
   22:      }
   23:  }

对ModelValidator创建方式的定制

DataAnnotationsModelValidatorProvider四个基于委托的静态字段体现了其采用的ModelValidator提供机制。由于它们都是内部字段,我们不能直接对其进行操作,但是如下所示的一系列静态方法在DataAnnotationsModelValidatorProvider中定义出来,使我们可以按照具体的需要对默认的ModelValidator进行定义。

    1:   public   class  DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
    2:  {
    3:       //其他成员   
    4:      public   static   void  RegisterAdapter(Type attributeType, Type adapterType);
    5:      public   static   void  RegisterAdapterFactory(Type attributeType, DataAnnotationsModelValidationFactory factory);
    6:      public   static   void  RegisterDefaultAdapter(Type adapterType);
    7:      public   static   void  RegisterDefaultAdapterFactory(DataAnnotationsModelValidationFactory factory);
    8:   
    9:      public   static   void  RegisterDefaultValidatableObjectAdapter(Type adapterType);
   10:      public   static   void  RegisterDefaultValidatableObjectAdapterFactory(DataAnnotationsValidatableObjectAdapterFactory factory);
   11:      public   static   void  RegisterValidatableObjectAdapter(Type modelType, Type adapterType);
   12:      public   static   void  RegisterValidatableObjectAdapterFactory(Type modelType, DataAnnotationsValidatableObjectAdapterFactory factory);
   13:  }

对于上面的8个静态方法,除了RegisterDefaultAdapter和RegisterValidatableObjectAdapter之外,其余的都很好理解。RegisterDefaultAdapter用于注册一个 默认的针对验证特性的ModelValidator类型 ,该类型必须具有一个参数类型列表为ModelMetadata、ControllerContext和Attribute的构造函数。如果根据 验证特性的类型找到了匹配的DataAnnotationsModelValidationFactory委托对象,相应的参数会被传入该构造函数并最终创建一个我们注册的ModelValidator对象。

RegisterValidatableObjectAdapter和RegisterDefaultAdapter比较类似,用于注册一个 默认的针对可验证对象类型的ModelValidator ,有该类型必须具有一个参数类型列表为ModelMetadata和ControllerContex的构造函数。如果根据 验证特性的类型找到了匹配的DataAnnotationsValidatableObjectAdapterFactory委托对象,相应的参数会被传入该构造函数并最终创建一个我们注册的ModelValidator对象。

ASP.NET MVC基于标注特性的Model验证:ValidationAttribute  
ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator  
ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider  
ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上  
ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则

作者: Artech
出处: http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类:  [01] 技术剖析

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelVali的详细内容...

  阅读:46次