ASP.NET MVC 页面生命周期
整个ASP.NET MVC框架是通过自定义的 HttpModule
和 HttpHandler
对ASP.NET 进行扩展构建起来的。
- 自定义的
HttpModule
:UrlRoutingModule
- 自定义的
HttpHandler
:MvcHandler
HttpApplication与HttpModule
HTTP请求由ASP.NET运行时接管之后,HttpRuntime
会利用 HttpApplicationFactory
创建或从 HttpApplication
对象池中取出一个HttpApplication
对象,同时ASP.NET会根据配置文件来初始化注册的HttpModule
,HttpModule
在初始化时会订阅HttpApplication
中的事件来实现对HTTP请求的处理。
ASP.NET MVC的入口在UrlRoutingModule
,它订阅了HttpApplication
的第7个管道事件PostResolveRequestCahce
,并且在HtttpApplication
的第7个管道事件处对请求进行了拦截。
UrlRoutingModule
通过在全局Web.Config中注册 System.Web.Routing.UrlRoutingModule
,IIS请求处理管道接到请求后,就会加载 UrlRoutingModule
类型的Init()方法,第7个管道事件 PostResolveRequestCahce
对请求进行了拦截。
当请求到达 UrlRoutingModule
的时候,UrlRoutingModule
取出请求中的 Controller、Action等RouteData信息,与路由表中的所有规则进行匹配,若匹配,把请求交给 IRouteHandler
,即 MVCRouteHandler
。
1 | //通过RouteCollection的静态方法GetRouteData获取到封装路由信息的RouteData实例 |
MVCRouteHadnler
MvcRouteHandler
在HttpApplication的第一个管道事件,使用 MapRoute()
方法注册路由的时候,通过Route
类的构造函数把MVCRouteHandler
注入到路由中。
1 | public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) |
MVCRouteHandler
是用来生成实现IHttpHandler
接口的MvcHandler
。
1 | namespace System.Web.Routing |
MvcHandler
第7个事件生成了 MvcHandler
。
第11和第12个事件之间调用了MvcHandler
的ProcessRequest
方法。
通过RouteHandler
的 GetHttpHandler()
方法获取到实现了IHttpHandler
接口的MVCHandler
。
1 | IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); |
MvcHandler
部分源码:
1 | public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState |
ControllerFactory
通过ControllerBuilder
的静态方法GetControllerFactory
获取到实现IControllerFactory
接口的ControllerFactory
。通过ControllerFactory
来创建指定名称的控制器,最后将控制器作为out参数传递出去。
ActionInvoker
ActionInvoker实现了IActionInvoker接口:
1 | public interface IActionInvoker |
MVC默认的ActionInvoker是ControllerActionInvoker。
ActionInvoker在执行InvokeAction()方法时会需要有关Controller和Action的相关信息,实际上,Controller信息(比如Controller的名称、类型、包含的Action等)被封装在ControllerDescriptor这个类中,Action信息(比如Action的名称、参数、属性、过滤器等)被封装在ActionDescriptor中。ActionDescriptor还提供了一个FindAction()方法,用来找到需要被执行的Action。
Filters
Filter->Action->Filter->Result
在ASP.NET MVC5中有常用的过滤器有5个:IAuthenticationFilter
、IAuthorizationFilter
、IActionFilter
、IResultFilter
、IExceptionFilter
。
在ASP.NET MVC中所有的过滤器最终都会被封装为Filter对象,该对象中FilterScope类型的属性Scope和int类型属性Order用于决定过滤器执行的先后顺序,具体规则如下:
- Order和FilterScope的数值越小,过滤器的执行优先级越高;
- Order比FilterScope具有更高的优先级,在Order属性值相同时FilterScope才会被考虑
1 | //数值越小,执行优先级越高 |
ActionResult
ActionResult是一个抽象类:
1 | public abstract class ActionResult |
如果ActionResult是非ViewResult,比如JsonResult, ContentResult,这些内容将直接被输送到Response响应流中,显示给客户端;如果是ViewResult,就会进入下一个渲染视图环节。
ViewEngine
默认的有Razor View Engine
和Web Form View Engine
,实现IViewEngine接口。
IViewEngine接口方法:
- FindPartialView
- FindView
- ReleaseView
参考:
ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程
ASP.NET MVC请求处理管道生命周期的19个关键环节(13-19)
ASP.NET MVC中的ActionFilter是如何执行的?
认识ASP.NET MVC的5种AuthorizationFilter