系列目录

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来“伪装”;用HttpPostAttributeHttpGetAttribute来说明某个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中与这四个接口相关的特性如下:

我们熟悉的有AuthorizeOutputCacheChildAction等。曾经,对于这些形形色色的Attribute,我都不能很好的理解和归类,现在总算是找它们各自的归宿了。

下一节,将针对这四个过滤器接口深入讨论一些细节问题。

劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/12/01/details-asp-net-mvc-07.html

深入理解ASP.NET MVC(7)的更多相关文章

  1. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  2. [转载]深入理解ASP.NET MVC之ActionResult

    Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionNam ...

  3. 深入理解ASP.NET MVC Day1

    深入理解ASP.NET MVC   ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上 ...

  4. 七天学会ASP.NET MVC ——深入理解ASP.NET MVC

    七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC   系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二) ...

  5. 深入理解ASP.NET MVC(6)

    系列目录 Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, acti ...

  6. 深入理解ASP.NET MVC(5)

    系列目录 回顾 系列的前4节深入剖析了ASP.NET URL路由机制,以及MVC在此基础上是如何实现Areas机制的,同时涉及到inbound和outbound很多细节部分.第2节中提到MvcRout ...

  7. 深入理解ASP.NET MVC(目录)

    学ASP.NET MVC2有一段时间了,也针对性的做了个练习.感觉这个框架还是不错的,所以决定要深入系统的学习一下.看到这样一本书: 作者博客:http://blog.stevensanderson. ...

  8. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_one.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会A ...

  9. [转载] ASP.NET MVC (一)——深入理解ASP.NET MVC

    个人认为写得比较透彻得Asp.net mvc 文章,所以转载过来,原文链接在最后: ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.N ...

  10. 理解ASP.NET MVC的路由系统

    引言 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请 ...

随机推荐

  1. 1) 上传多张图片时 ,对 $_FILES 的处理. upload ; 2)fileinput 上传多张图片. 3) 修改,删除的时候删除原来的资源,图片 update, delete , 删除 4)生成器中两个字段上传图片的时候,要修改生成器生成的代码

    1上传多张图片, 要对 $_FILES进行 重新处理. //添加 public function addCourseAlbumAction() { $CourseAlbumModel = new Co ...

  2. String中对字符串进行操作的一些方法

    1.substring 作用:根据字符串下标进行截取 public class StrTest { public static void main(String[] args) { String a ...

  3. ES6 声明变量的6种方法

    ES5 只有两种声明变量的方法:var命令和function命令. ES6除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和class命令.所以,ES6 一共 ...

  4. spring — jdbc 配置文件的设置

    ---参考配置,  链接mysql 数据库 <!-- 1.配置数据源 --><bean id="dataSource" class="org.sprin ...

  5. 大数据-02-Scala入门

    Scala 简介 它是一门基于JVM的面向函数和面向对象的编程语言, 它包含了求值表达式,闭包,切片操作,模式匹配,隐式转换等特性. 可变量/不可变量 可变集合/不可变集合.集合操作 函数 值函数 求 ...

  6. 查询表Or列的注释信息

    需求:开发人员需要DBA支持,查询表的注释说明,用于明确表的用途. 1.测试 session 1 创建测试表SQL> create table a_emp as select * from sc ...

  7. 测试那些事儿—web测试方法之输入框

    一.字符型输入 (1)字符型输入框 英文全角,英文半角,数字,空或者空格,特殊字符“~!@#¥%.......&*?{}[]"特别要注意单引号和&符号.禁止直接输入特殊字符时 ...

  8. TS 基础数据类型

    1.基础数据类型 Boolean布尔值   Number数字 String字符串  Array数组 Tuple元组  Enum枚举   Any    void Boolean布尔值:true/fals ...

  9. NYOJ 47:过河问题(思维)

    47-过河问题 内存限制:64MB 时间限制:1000ms 特判: No 通过数:6 提交数:10 难度:5 题目描述: 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话 ...

  10. Linux更改yum源

    环境 centos6 阿里云镜像地址 https://opsx.alibaba.com/mirror(本篇所选) centos官网镜像 http://mirror.centos.org/ 网易云镜像地 ...