先来熟悉下asp.net请求管道
1.当客户端发送http://localhost:80/home/index请求时
2.首先到达服务端的内核模块HTTP.SYS(它监听80端口),通过访问注册表,将请求转交给IIS处理
3.IIS中w3svc服务访问IIS核心进程InetInfo.exe中元数据信息,获取请求交给哪个具体的WorkProcess进行处理 (IIS6中有多个WorkProcess工作进程 它是.Net代码执行所在的宿主)
5.具体的WorkProcess将请求交给aspnet_isapi.dll(非托管的Com组件 它负责启动.net运行时 将请求信息交给运行时ISAPIRuntime)
6.ISAPIRuntime的PR方法通过ECB指针创建HttpWorkProcess对象 传入HttpRuntime中
7.HttpRuntime的PR方法通过HttpWorkProcess对象 封装出HttpContext对象(包含HttpRequest HttpResponse Session...)
8.再通过HttpApplicationFactory获取HttpApplication实例
如果是第一次请求,做两件事
1.会编译Global.asax成HttpApplication类型 创建特殊应用程序池 调用池中特殊Application对象的Application_Start方法
2.从池子中获取一个普通的HttpApplication实例 如果池子是空的 则通过Global.asax反射得到(MVC中得到的就是MVCApplication),同时调用HttpApplication实例的Init()方法,方法内部初始化所有的HttpMoudle(配置文件中所有HttpMoudle)UrlRouteMoudlue在此时初始化
说这么多您可能不理解 我们通过Reflect反编译看下源码的执行过程 如下图:
-
路由模块对象以及路由注册、路由数据获取
上述有个要点需要重复下,就是Application_Start方法中路由的注册
这里就扯到MVC的路由了,下图阐述路由模块锁涉及的几大对象以及Application_Start方法中进行的路由注册,同时简要说明RouteTable是如何通过请求地址获得最终的RouteData路由数据的
-
UrlRouteMoudle内部
在接下来看看UrlRouteMoudle的Init方法中究竟做了些什么?它是如何将原本的请求处理Handler"转交"给MvcHandler的
源码如下:
public class UrlRoutingModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.PostResolveRequestCache += OnPostResolveRequestCache; } protected virtual void OnPostResolveRequestCache(object sender, EventArgs e) { //封装当前上下文至HttpContextWrapper中 HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); //根据上下文信息 从路由表RouteTable 中的路由集合RouteCollection 获取路由数据RouteData //RouteTable数据在Application_Start中填充 RouteData routeData = RouteTable.Routes.GetRouteData(httpContext); if(null == routeData) {//如果路由数据不存在 return; } //将传入的HttpContextWrapper上下文信息与路由数据封装至新的RequestContext上下文 供后续RouteHandler使用 RequestContext requestContext = new RequestContext { RouteData = routeData, HttpContext = httpContext }; //路由数据 通过 RouteHandler 获取真正处理请求的IHttpHandler对象 ->实质就是MvcHandler对象 IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext); //将原始请求 重定向到当前的IHttpHandler上 (从原有WebForm中的IHttpHandler切至MvcHandler) httpContext.RemapHandler(handler); } }
图析如下:
-
MVCHandler
接下来无疑是进入MVCHandler的具体处理了,如何创建控制器,控制器如何执行方法... 这方面没有深入的了解,只知道个大概,
通过ControllerFactory创建Controller,
通过ExecuteResult获取执行结果
通过Render渲染视图
完整流程图如下:
原文来自 痞子一毛 Asp.Net MVC请求处理图解一文