上节:ASP.NET MVC ActionResult内幕-MVC原理系列6,我们深入理解了ASP.NET MVC ActionResult相关知识。
本节我们来分析一下ASP.NET MVC中Action的定位,再入深入理解ASP.NET MVC的四种过滤器知识,从而更好的掌握MVC开发技巧。
下面让我们再次回到Controller的ExecuteCore方法,回到action调用的入口,继续我们上节的分析:
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的查找过程设计了两种“选择器”
如果对此比较迷茫的话,看了他们的派生特性,你也许就明白了:
我们常用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(六)
当ActionDescriptor(ReflectedActionDescriptor)返回后,ContollerActionInvoker开始执行action,但是在执行action前还有一些额外的步骤,那就是过滤。以下四个是MVC内建的过滤接口:
这四个Filter会被ControllerActionInvoker框架综合考量,下面的伪代码说明了ControllerActionInvoker处理他们的逻辑顺序:
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,我都不能很好的理解和归类,现在总算是找它们各自的归宿了。
本节:ASP.NET MVC IActionFilter过滤器内幕-MVC原理系列7,就介绍到这里了,让我们继续深入理解ASP.NET MVC。
2011/9/8 0:37:49 | ASP.NET MVC教程 | |
┣財布
┣小物
┣靴
┣時計
┗2018年 新作の展示
2018年ルイヴィトン全新登場
2018年超人気商品!随時更新
品質がよい、価格が低い、実物写真!
全物品運賃無料(日本全国)
不良品物情況、無償で交換します.
税関没収する商品は再度無料で発送します.
注文数量: 数量制限無し、一個の注文も、OKです
注意:注文は多くて、特恵は多いです
広大な客を歓迎して買います!