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?》中]
一、ControllerDescriptorControllerDescriptor包含了用于描述某个Controller的元数据信息。如下面的代码片断所示,ControllerDescriptor具有三个属性,其中ControllerName和ControllerType分别表示Controller的名称和类型,前者来源于路由信息;字符串类型的UniqueId表示ControllerDescriptor的唯一标识,该标识由自身的类型、Controller的类型以及Controller的名称三者派生。
1: public abstract class ControllerDescriptor : ICustomAttributeProvider
4: public virtual object[] GetCustomAttributes(Type attributeType, bool inherit);
6: public virtual IEnumerable FilterAttribute GetFilterAttributes(bool useCache);
8: public abstract ActionDescriptor FindAction(ControllerContext controllerContext, string actionName);
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接口的实现。
6: public override object[] GetCustomAttributes(Type attributeType, bool inherit);
7: public override IEnumerable FilterAttribute GetFilterAttributes(bool useCache);
10: public override ActionDescriptor FindAction( ControllerContext controllerContext, string actionName);
对于GetCanonicalActions方法返回的用于描述所有Action方法的ActionDescriptor数组,仅限于公有实例方法,但是从.Controller中继承下来的方法除外。当我们调用FindAction方法根据Action名称获取对应ActionDescriptor的时候,在默情况下会将方法名称视为Action名称进行匹配。如果方法上应用了具有如下定义的ActionNameSelectorAttribute特性,会传入相应的参数调用其IsValidName方法,如果该返回值为True,目标方法会被认为是匹配的Action方法。
1: [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
4: public abstract bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo);
顾名思义,抽象类ActionNameSelectorAttribute是一个用于辅助选择目标Action方法的特性,在ASP.NET MVC应用编程接口中具有一个类型为ActionNameAttribute的继承者。ActionNameAttribute特性应用于Action方法通过参数值指定一个Action别名,在实现的IsValidName方法中会比较指定的别名是否和当前的Action名称相匹配。如果具有不同 的Action选择规则,我们也可以通过自定义ActionNameSelectorAttribute特性的方式来实现。
1: [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
5: public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo);
对于FindAction方法,如果找不到与指定Action名称的Action方法,则返回Null,而最终会导致一个状态码为404的HttpException异常的抛出;如果具有多个匹配的Action方法,则直接抛出AmbiguousMatchException异常。也就是说对于每一次请求,要求有且只有一个匹配的Action方法。
三、ReflectedAsyncControllerDescriptorReflectedAsyncControllerDescriptor类型为ReflectedControllerDescriptor的异步版本。如下面的代码片断所示,ReflectedAsyncControllerDescriptor和ReflectedControllerDescriptor具有类似的成员定义,实际上除了FindAction和GetCanonicalActions两个方法,其他方法的实现逻辑(即对应用在Controller类型上的相关特性的解析)与ReflectedControllerDescriptor完全一致。
6: public override object[] GetCustomAttributes(Type attributeType, bool inherit);
7: public override IEnumerable FilterAttribute GetFilterAttributes( bool useCache);
10: public override ActionDescriptor FindAction( ControllerContext controllerContext, string actionName);
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
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 原文链接
基于Asp.Net Mvc开发的个人博客系统 一个基于Mvc 5构建的简单、代码层级分明的开源个人博客系统。前端美观大气、后台采用RightControl .NET通用角色权限系统,开发简单、效率高。网站配置采用XML配置,灵活可以根据自己是需求进行个性化配置。系统功能完备,完全可以满足需求,基本不用二次开发,非常使用程序员的个人博客。
Java Spring Boot开发实战系列课程【第7讲】:Spring Boot 2.0安全机制与MVC身份验证实战(Java面试题) 立即下载
相关文章
- .NET Core如何配置TLS Cipher(套件)?
- 如何创建一个基于 .NET Core 3 的 WPF 项目
- ASP.Net MVC – What are the uses of Display, DisplayName, DisplayFormat and ScaffoldColumn attributes
- 学习ASP.NET Core Blazor编程系列四——迁移
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之二(三十八)
- abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理二 (二十)
- 学习ASP.NET MVC(四)——我的第一个ASP.NET MVC 实体对象
- Differences Between ASP.NET URL Authorization and IIS URL Authorization
- Understanding the ASP.NET MVC Execution Process
- 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生
- 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等) 图片放大镜 JavaScript-基础 用javascript写原生ajax(笔记) 初遇 Asp.net MVC 数据库依赖缓存那些事儿 前端JS 与 后台C# 之间JSON序列化与反序列化(笔记)
- Python3 与 C# 面向对象之~继承与多态 Python3 与 C# 面向对象之~封装 Python3 与 NetCore 基础语法对比(Function专栏) [C#]C#时间日期操作 [C#]C#中字符串的操作 [ASP.NET]NTKO插件使用常见问题 我对C#的认知。
- ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
- C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理
- 如何应用ASP.NET MVC中的分部视图
- ASP.NET MVC异步验证是如何工作的01,jQuery的验证方式、错误信息提示、validate方法的背后
- 再议ASP.NET MVC中CheckBoxList的验证
- 在ASP.NET MVC中使用Knockout实践01,绑定Json对象
- 查看是否安装.NET Framework、.NET Framework的版本号、CLR版本号
- ASP.NET Core Web API下事件驱动型架构的实现(五):在微服务中使用自我监听模式保证数据库更新与消息派发的可靠性
- csharp:asp.net Importing or Exporting Data from Worksheets using aspose cell
- ASP.NET MVC基础
- 转载-asp.net id 和name的区别
- 精通 ASP.NET Core MVC (第 7 版) 源码下载
- Asp.Net Cache缓存技术学习
- ASP.NET MVC+BUI实现表格的操作