好得很程序员自学网

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

ASP.NET MVC三个重要的描述对象:ControllerDescriptor

ASP.NET MVC三个重要的描述对象:ControllerDescriptor

ASP.NET MVC应用的请求都是针对某个Controller的某个Action方法,所以对请求的处理最终体现在对目标Action方法的执行。而Action方法具有相应的参数,所以在方法执行之前必须根据相应的规则从请求中提取相应的数据并将其转换为Action方法参数列表,我们将这个过程称为Model绑定。在ASP.NET MVC应用编程接口中,Action方法某个参数的元数据通过 ParameterDescriptor 表示,而两个相关的类型 ControllerDescriptor 和 ActionDescriptor 则用于描述Controller和Action方法。[本文已经同步到《 How ASP.NET MVC Works? 》中]

一、ControllerDescriptor

ControllerDescriptor包含了用于描述某个Controller的元数据信息。如下面的代码片断所示,ControllerDescriptor具有三个属性,其中ControllerName和ControllerType分别表示Controller的名称和类型,前者来源于路由信息;字符串类型的UniqueId表示ControllerDescriptor的唯一标识,该标识由 自身的类型 、 Controller的类型 以及 Controller的名称 三者派生。

    1:   public   abstract   class  ControllerDescriptor : ICustomAttributeProvider
    2:  {   
    3:        public   virtual   object [] GetCustomAttributes( bool  inherit);
    4:        public   virtual   object [] GetCustomAttributes(Type attributeType,  bool  inherit);
    5:        public   virtual   bool  IsDefined(Type attributeType,  bool  inherit);
    6:        public   virtual  IEnumerable<FilterAttribute> GetFilterAttributes( bool  useCache);
    7:   
    8:        public   abstract  ActionDescriptor FindAction(ControllerContext controllerContext,  string  actionName);
    9:        public   abstract  ActionDescriptor[] GetCanonicalActions();
   10:    
   11:       public   virtual   string  ControllerName { get; }
   12:       public   abstract  Type ControllerType { get; }
   13:       public   virtual   string  UniqueId { get; }
   14:  }
   15:   
   16:   public   interface  ICustomAttributeProvider
   17:  {
   18:       object [] GetCustomAttributes( bool  inherit);
   19:       object [] GetCustomAttributes(Type attributeType,  bool  inherit);
   20:       bool  IsDefined(Type attributeType,  bool  inherit);
   21:  }

ControllerDescriptor实现了 ICustomAttributeProvider 接口,意味着我们可以通过调用GetCustomAttributes和GetCustomAttributes方法获取应用在Controller类型上的所有自定义特性或者给定类型的特性,也可以调用IsDefined方法判断指定的自定义特性类型是否应用在对应的Controller类型上。

另一个方法GetFilterAttributes用于获取应用在Controller上的所有筛选器特性(继承自抽象类 FilterAttribute )。筛选器是一种基于AOP的设计,它使我们可以一些基于横切关注点相关逻辑的执行动态的注入到Action方法的执行前后,我们会在“Action方法的执行”中对筛选器进行详细地介绍。

ControllerDescriptor的FindAction方法根据指定的Controller上下文和名称得到相应的Action方法,返回的是用于描述Action方法的ActionDescriptor对象。而GetCanonicalActions得到当前Controller的所有Action方法,返回类型为ActionDescriptor数组。

二、ReflectedControllerDescriptor

在ASP.NET MVC应用编程接口中定义了抽象类ControllerDescriptor的唯一继承类型 ReflectedControllerDescriptor 。顾名思义,ReflectedControllerDescriptor通过反射的机制解析用于描述Controller的元数据。如下面的代码片断所示,表示Controller类型的ControllerType属性在构造函数中指定。ReflectedControllerDescriptor通过反射的方式获取应用在Controller类型上的相关特性以提供针对ICustomAttributeProvider接口的实现。

    1:   public   class  ReflectedControllerDescriptor : ControllerDescriptor
    2:  {
    3:       public  ReflectedControllerDescriptor(Type controllerType);
    4:     
    5:       public   override   object [] GetCustomAttributes( bool  inherit);
    6:       public   override   object [] GetCustomAttributes(Type attributeType,  bool  inherit);
    7:       public   override  IEnumerable<FilterAttribute> GetFilterAttributes( bool  useCache);
    8:       public   override   bool  IsDefined(Type attributeType,  bool  inherit);
    9:   
   10:       public   override  ActionDescriptor FindAction( ControllerContext controllerContext,  string  actionName);
   11:       public   override  ActionDescriptor[] GetCanonicalActions();
   12:   
   13:       public   sealed   override  Type ControllerType { get; }
   14:  }

对于GetCanonicalActions方法返回的用于描述所有Action方法的ActionDescriptor数组,仅限于 公有实例方法,但是从 .Controller 中继承下来的方法除外 。当我们调用FindAction方法根据Action名称获取对应ActionDescriptor的时候,在默情况下会将方法名称视为Action名称进行匹配。如果方法上应用了具有如下定义的 ActionNameSelectorAttribute 特性,会传入相应的参数调用其IsValidName方法,如果该返回值为True,目标方法会被认为是匹配的Action方法。

    1:  [AttributeUsage(AttributeTargets.Method, AllowMultiple =  false ,  Inherited =  true )]
    2:   public   abstract   class  ActionNameSelectorAttribute : Attribute
    3:  {
    4:       public   abstract   bool  IsValidName(ControllerContext controllerContext,  string  actionName, MethodInfo methodInfo);
    5:  }

顾名思义,抽象类ActionNameSelectorAttribute是一个用于辅助选择目标Action方法的特性,在ASP.NET MVC应用编程接口中具有一个类型为 ActionNameAttribute 的继承者。ActionNameAttribute特性应用于Action方法通过参数值指定一个Action别名,在实现的IsValidName方法中会比较指定的别名是否和当前的Action名称相匹配。如果具有不同 的Action选择规则,我们也可以通过自定义ActionNameSelectorAttribute特性的方式来实现。

    1:  [AttributeUsage(AttributeTargets.Method, AllowMultiple= false , Inherited= true )]
    2:   public   sealed   class  ActionNameAttribute : ActionNameSelectorAttribute
    3:  {    
    4:       public  ActionNameAttribute( string  name);
    5:       public   override   bool  IsValidName(ControllerContext controllerContext,  string  actionName, MethodInfo methodInfo);
    6:       public   string  Name { get; }
    7:  }

对于FindAction方法,如果找不到与指定Action名称的Action方法,则返回Null,而最终会导致一个状态码为 404 的HttpException异常的抛出;如果具有多个匹配的Action方法,则直接抛出 AmbiguousMatchException 异常。也就是说 对于每一次请求,要求有且只有一个匹配的Action方法 。

三、ReflectedAsyncControllerDescriptor

ReflectedAsyncControllerDescriptor 类型为ReflectedControllerDescriptor的异步版本。如下面的代码片断所示,ReflectedAsyncControllerDescriptor和ReflectedControllerDescriptor具有类似的成员定义,实际上除了FindAction和GetCanonicalActions两个方法,其他方法的实现逻辑(即对应用在Controller类型上的相关特性的解析)与ReflectedControllerDescriptor完全一致。

    1:   public   class  ReflectedAsyncControllerDescriptor : ControllerDescriptor
    2:  {  
    3:       public  ReflectedAsyncControllerDescriptor(Type controllerType);
    4:      
    5:       public   override   object [] GetCustomAttributes( bool  inherit);
    6:       public   override   object [] GetCustomAttributes(Type attributeType,   bool  inherit);
    7:       public   override  IEnumerable<FilterAttribute> GetFilterAttributes(  bool  useCache);
    8:       public   override   bool  IsDefined(Type attributeType,  bool  inherit);
    9:   
   10:       public   override  ActionDescriptor FindAction( ControllerContext controllerContext,  string  actionName);
   11:       public   override  ActionDescriptor[] GetCanonicalActions();
   12:    
   13:       public   sealed   override  Type ControllerType { get; }
   14:  }

ReflectedAsyncControllerDescriptor的GetCanonicalActions总是返回一个空的ActionDescriptor数组。对于继承自AsyncController的Controller类型,一个异步Action方法由两个匹配的方法( {ActionName}Async和{ActionName}Completed )构成,ReflectedAsyncControllerDescriptor在根据指定的Action名称对方法成员进行匹配的时候会自动忽略掉方法名称的“Async”和“Completed”后缀。

ASP.NET MVC三个重要的描述对象:ControllerDescriptor  
ASP.NET MVC三个重要的描述对象:ActionDescriptor  
ASP.NET MVC三个重要的描述对象:ControllerDescriptor与ActionDescriptor的创建机制  
ASP.NET MVC三个重要的描述对象:ParameterDescriptor

作者: Leo_wl

    

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

    

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

版权信息

查看更多关于ASP.NET MVC三个重要的描述对象:ControllerDescriptor的详细内容...

  阅读:37次