深入理解ASP.NET MVC(7)
Action的定位
再次回到Controller的ExecuteCore方法,回到action调用的入口:
|
1
|
if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) |
这里的ActionInvoker是个IActionInvoke,它无疑是负责了所有action的调用逻辑,MVC中默认实现这个接口的是ControllerActionInvoke。可以想象ControllerActionInvoke面临的第一个问题是如何找到与actionName对应的action。
首先,并不是所有的action都合法,需要符合下面条件:
1、Public,非static
2、非Controller或其基类定义的方法,比如ToString(),GetHashcode()
3、不能是特殊名字System.Reflection.MethodBase的IsSpecialName标志,例如构造函数,属性包装器,事件包装器
4、具有泛型参数的方法尽管会被认为是action,但框架试图执行这样的action时会只是抛出异常。
其次,MVC为action的查找过程设计了两种“选择器”
- ActionNameSelectorAttribute
- ActionMethodSelectorAttribute
如果对此比较迷茫的话,看了他们的派生特性,你也许就明白了:
![]()
![]()
我们常用ActionNameAttribute来“伪装”;用HttpPostAttribute或HttpGetAttribute来说明某个action符合的特定的http行为;用NoAction隐藏我们不想“暴露给url”的方法…其实这些行为的原理便是利用MVC为我们提供的action选择的机制。下面这张图说明了这个过程的完成逻辑:
![]()
ContollerActionInvoker.InvokeAction在内部创建一个ReflectedControllerDescriptor,并调用其FindAction方法,这个对象的FindAction负责调用一个ActionMethodSelector对象实现上述逻辑,并在最后返回一个ReflectedActionDescriptor。 ActionMethodSelector对象故名思意,原理上用反射执行上述过程,执行的结果要么返回一个MethodInfo,要么返回null,要 么抛出异常。ReflectedControllerDescriptor对返回值判断,如果是null,则也返回null;如果是 MethodInfo,则将其包装成ReflectedActionDescriptor返回。对于外面的InvokeAction方法来说只要 ReflectedControllerDescriptor返回的ReflectedActionDescriptor为空就返回false,否则继 续。Controller负责对返回false的情况调用HandleUnknownAction,该方法默认产生404错误,我们可以重写它。
在回过头来看看上图的逻辑,不难得到这样一个事实:ActionNameSelectorAttribute优先于ActionMethodSelectorAttribute,ActionMethodSelectorAttribute优先于没有ActionMethodSelectorAttribute特性的方法。
更多关于这部分源码的细节,可以参考:通过源代码研究ASP.NET MVC中的Controller和View(六)
MVC的内建过滤器
当ActionDescriptor(ReflectedActionDescriptor)返回后,ContollerActionInvoker开始执行action,但是在执行action前还有一些额外的步骤,那就是过滤。以下四个是MVC内建的过滤接口:
- IActionFilter
- IAuthorizationFilter
- IExceptionFilter
- IResultFilter
这四个Filter会被ControllerActionInvoker框架综合考量,下面的伪代码说明了ControllerActionInvoker处理他们的逻辑顺序:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
try{ //依次执行IAuthorizationFilter Run each IAuthorizationFilter's OnAuthorization() method //所有的IAuthorizationFilter都返回null而不是ActionResult if(none of the IAuthorizationFilters cancelled execution) { Run each IActionFilter's OnActionExecuting() method Run the action method //注意到这里按照反转顺序进行 Run each IActionFilter's OnActionExecuted() method (in reverse order) Run each IResultFilter's OnResultExecuting() method Run the action result //注意到这里按照反转顺序进行 Run each IResultFilter's OnResultExecuted() method (in reverse order) } //有IAuthorizationFilter返回ActionResult else { Run any action result set by the authorization filters }}catch(exception not handled by any action or result filter){ //注意到IExceptionFilter处理的异常只在这个try catch块中 Run each IExceptionFilter's OnException() method Run any action result set by the exception filters} |
需要注意的事项,在代码中都已经给出注释,在后面一节中,将讨论其中的某些细节。
MVC中与这四个接口相关的特性如下:
![]()
我们熟悉的有Authorize,OutputCache,ChildAction等。曾经,对于这些形形色色的Attribute,我都不能很好的理解和归类,现在总算是找它们各自的归宿了。
下一节,将针对这四个过滤器接口深入讨论一些细节问题。
劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/12/01/details-asp-net-mvc-07.html
深入理解ASP.NET MVC(7)的更多相关文章
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...
- [转载]深入理解ASP.NET MVC之ActionResult
Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionNam ...
- 深入理解ASP.NET MVC Day1
深入理解ASP.NET MVC ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上 ...
- 七天学会ASP.NET MVC ——深入理解ASP.NET MVC
七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二) ...
- 深入理解ASP.NET MVC(6)
系列目录 Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, acti ...
- 深入理解ASP.NET MVC(5)
系列目录 回顾 系列的前4节深入剖析了ASP.NET URL路由机制,以及MVC在此基础上是如何实现Areas机制的,同时涉及到inbound和outbound很多细节部分.第2节中提到MvcRout ...
- 深入理解ASP.NET MVC(目录)
学ASP.NET MVC2有一段时间了,也针对性的做了个练习.感觉这个框架还是不错的,所以决定要深入系统的学习一下.看到这样一本书: 作者博客:http://blog.stevensanderson. ...
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】
http://www.cnblogs.com/powertoolsteam/p/MVC_one.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会A ...
- [转载] ASP.NET MVC (一)——深入理解ASP.NET MVC
个人认为写得比较透彻得Asp.net mvc 文章,所以转载过来,原文链接在最后: ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.N ...
- 理解ASP.NET MVC的路由系统
引言 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请 ...
随机推荐
- ‘’.join(列表)--列表转化为一个语句。 strip()删除掉str中的左右的空白字符
1和2相比,删除掉了str左右的空白字符,2和3相比,删除掉了上下的空白字符
- input默认显示当前时间
方法一: // 获取当天的年月日 new Date().getFullYear() + '-' + (new Date().getMonth() + 1) + '-' + new Date().get ...
- js--未来元素
通过动态生成的标签,在生成标签直接绑定事件是无效的. eg:html标签 <div id="tree"> </div> <script> $(' ...
- Insert插入不同的列数量,统计信息对比
一.实验目的: Insert插入表中相同的行数量,不同的列数量,通过10046 和autotrace工具对比查看逻辑读.物理读.time数据,并得出相应结论 二.测试 2.1测试流程: =>[为 ...
- Python3中的运算符
一.Python3中的运算符 强调这是Python3中的运算符 + 加法 - 减法 * 乘法 / 除法 // 整除,只要整数部分 ** 幂运算 % 取余数 ...
- 第8次Scrum会议(10/20)【欢迎来怼】
一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/20 17:20~17:45,总计25min. 地点 ...
- Python算法——递归思想
编程语言在构建程序时的基本操作有:内置数据类型操作.选择.循环.函数调用等,递归实际属于函数调用的一种特殊情况(函数调用自身),其数学基础是数学归纳法.递归在计算机程序设计中非常重要,是许多高级算法实 ...
- MySQL数据库一
MySQL的基本命令: 进入数据库: mysql -u [username] -p[password] (注:-u 和 用户名之间可以有空格 -p和password之间无空格) mysql -u ...
- C++学习(一)之Visual Studio安装以及首次使用
一.安装Visual Studio 首先下载Visual Studio 链接: http://pan.baidu.com/s/1pLhJt0Z 密码:uqyc 将.ios文件解压得到以下文件: 点击v ...
- [zoj4046][树状数组求逆序(强化版)]
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4046 题意:有一个含有n个元素的数列p,每个元素均不同且为1~n中的一个, ...