ASP.NET MVC之Action的执行
2010-07-22 21:51 by Creason New, 1880 visits, 收藏, 编辑
内容概览Top
先说说FilterTop
Filter是的重要性不言而喻,作为AOP的一种实践,虽然Filter的类型不尽相同,执行的时间也不太一样,但有一个共同点就是围绕着Action做文章。所以,Action的执行是离不开Filter的,说到Action必须先明白Filter。
ASP.NET MVC有这么几种类型的Filter:在Action前后执行的IActionFilter,在ActionResult返回前后执行的IResultFilter,验证作用的IAuthorizationFilter,捕获异常的IExceptionFilter。平时用到的大多是前三种。它们实行时要依赖一个上下文对象XXXContext,XXXContext继承自ControllerContext,还扩展了一些自己的属性。Filter在运行时的获取和分类在上一篇中已经介绍过了。
Filter和Action的执行Top
在Controller类的InvokeAction方法中,我们先是获取了ControllerDescriptor再是ActionDescriptor,然后又获取到了所有的Filter,并把它们分门别类的存了起来。这么多的准备工作终于完成了,下一步就是执行Action和Filter了。
在InvokeAction方法中,有一段try...catch语句,这段就是执行Action和Filter的语句了。
try {
AuthorizationContext authContext = ①InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
if (authContext.Result != null) {
// the auth filter signaled that we should let it short-circuit the request
②InvokeActionResult(controllerContext, authContext.Result);
}
else {
if (controllerContext.Controller.ValidateRequest) {
ValidateRequest(controllerContext.HttpContext.Request);
}
IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
ActionExecutedContext postActionContext = ③InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
④InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
}
}
catch (ThreadAbortException) {
// This type of exception occurs as a result of Response.Redirect(), but we special-case so that
// the filters don't see this as an error.
throw;
}
catch (Exception ex) {
// something blew up, so execute the exception filters
ExceptionContext exceptionContext = ⑤InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
if (!exceptionContext.ExceptionHandled) {
throw;
}
⑥InvokeActionResult(controllerContext, exceptionContext.Result);
}
我们知道有的Filter是在Action执行之前执行,有的则是其后,那么这几种类型Filter执行的顺序是IAuthorizationFilter, IResultFilter, IActionFilter, IActionFilter, IResultFilter.
所以先执行上面代码中的①,InvokeAuthorizationFilters方法也很简单,就是遍历得到的AuthorizationFilter的集合,执行每一个Filter的OnAuthorize方法,如何Result!=null,就说明没有验证通过,执行②,如果验证通过,则执行③④,③④的作用是执行Action和Filter。如果有异常发生,就执行⑤⑥。
就这样,Action和Filter就都执行完毕了。
万总归一——ActionResultTop
我们Go To Defination到上面的5个方法,发现除了InvokeActionMethodWithFilter之外其它方法都最终调用到了InvokeActionResult方法。InvokeActionResult只有一行语句:
actionResult.ExecuteResult(controllerContext);
ActionResult类是一个抽象类,Action返回用户的类型也必须是ActionResult类型的,ActionResult抽象了视图引擎的所有返回类型。最终,天下大一统,给用户输出的任务就交给了ActionResult,而我们的视图引擎会搞好这一切。
作者:Creason New(Creason's Blog)
出处: http://www.cnblogs.com/niuchenglei
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。