出处:https://www.cnblogs.com/Joans/archive/2012/02/08/2342887.html
疑惑?从客户端发出一个请求,请求到达服务端如何和IIS关联起来?IIS又如何读取我发布的代码并返回服务器上的文件?
整个流程如下:
1、从浏览器输入一个地址http://localhost:8001/Account/Login回车,就发送了一个请求,请求会根据请求头或者IP和端口号找到相应的服务器站点。
2、根据http协议,当请求到达相应的主机服务器时,服务器上的系统进程http.sys(能够让任何应用程序通过它提供的接口,以http协议进行信息通讯。可以理解为专门处理http请求的进程)就会接收。
3、http.sys进程接收到请求信号后,传递给应用程序池的工作者进程,即IIS进程inetinfo.exe(inetinfo.exe是Windows系统下的iis进程,主要用于支持微软Windows IIS网络服务的Debug调试除错)。这时候服务器进IIS关联起来了。
4、IIS进程可以处理一般的HTML静态页面,处理完后直接找到静态页面HTML后返回给客户端显示。如果是.aspx或者cshtml页面,IIS就不能直接处理了,IIS进程需要加载aspnet_isapi.dll(这个DLL文件是asp底层类库,是asp.net的处理文件,用于处理asp.net在iis注册过扩展名的文件)进程。
5、当ISAPI接收到处理请求后,会启动ASP.NET工作进程,然后将请求信息转交给ASP.NET工作进程ASPNET_WP.EXE。这时候IIS就和ASP.NET关联起来了,这时候控制权就交给了ASPNET_WP.EXE进程。
6、当控制权由ASPNET_WP.EXE掌控后,如果没有执行.net的环境,会先建立APPDOMAIN应用程序域,在APPDOMAIN建立时, ISAPIRUNTIME和HttpRuntime这两个类会作为APPDOMAIN的一部分被实例化。【APPDOMAIN就是一个能够处理aspnet进程(.dll)的环境或应用程序域,我们知道ASP.NET程序的运行需要以.NET Framework为基础平台,通过CLR(公共语言运行库)托管才能运行。ASP.NET是一个复杂的使用托管代码来从头到尾处理Web请求的引擎.
APPDOMAIN中有几个重要的对象。
ISAPIRUNTIME:专门负责解出http请求的必要信息,它将信息和请求转交给HttpRuntime。
HttpRunTime:主要的工作便是为每一个提出请求的客户建立一个HttpContext对象.这个东东又管理着HttpSession对象.
每一个访问者有各自的HttpContext对象和HttpSession对象,这些对象,你可以在.NET FRAMEWORK库中找到对应的类名,像System.Web.HttpContext,System.Web.
HttpSessionState等.这两个对象是APPDOMAIN运行环境的一部分。这两个类的全称为System.Web.Hosting.ISAPIRuntime,System.Web.HttpRuntime。】
7、当APPDOMAIN初始化完成后,就需要建立对话,将请求传递给其中的一个类HttpRunTime,他们之间的创建关系:HttpRuntime负责创建HttpContext和HttpSession,httpContext负责管理httpSession。
从提交http请求开始一直到这(HttpRuntime创建完httpContext为止),实际上,我们在服务器上发布的应用程序仍然没有运行,或者说,请求者的请求实际上并未真正的被处理,前面的工作都是些准备性或者辅助性的工作.
8、接下来,HttpRuntime除了负责创建HttpContext和HttpSession外,还要创建了一个重要的对象HttpApplication。HttpApplication调用ProcessRequest方法来处理用户请求,具体说就是创建一个HttpContext实例,
9、HttpRuntime使用上下文信息查找或新建能处理该请求的WEB应用程序的对象。由HttpApplication Factory负责返回HttpApplication实例。HttpApplication对象使用IHttpHandlerFactory类型的实例返回HttpHandler(http处理程序)给HttpRuntime对象。一个页面只是个http处理程序对象。
最后由HttpRuntime对象调用IHttpHandler的页面对象的ProcessRequest方法。HttpHandler根据用户请求文件的扩展名处理请求,并把请求的结果,也就是HTML发送到客户浏览器.
在MVC源码中MvcHandler类继承了接口IHttpHandler,并实现了ProcessRequest(HttpContext httpContext)方法,该方法是MVC程序运行的入口。
10、此时,很想知道mvc中的路由是如何跟HttpApplication联系起来的呢,UrlRoutingModule 如何截获HttpApplicatioin的管道事件,从而把Http Request 引入Mvc框架中的。
在UrlRoutingModule.cs文件中,看到当UrlRoutingModule初始化并调用Init方法的时候注册了HttpApplication的 PostResolveRequestCache管道事件,所以当HttpAplication对象(这里是MvcApplication)执行时就会触 发PostResolveRequestCache事件,从而把HttpRequest引导进MVC module中
在ASP.NET MVC程序中首先涉及的部件是UrlRoutingModule,它是System.Web.Routing的一部分。UrlRoutingModule 用于第一次检查请求的url和本地磁盘中的文件是否相匹配。如果匹配,UrlRoutingModule会将请求直接回发给IIS,IIS根据地址来进行 相应处理。如果UrlRoutingModule没有在磁盘中找到匹配的文件。它会检查RouteCollection结构来决定是否继续传递请 求.UrlRoutingModule会引入RouteHandler和匹配的路径入口(默认情况下是MvcRouteHandler)。而后会引入合适 的HttpHandler来处理和请求有关的逻辑。默认情况下,这个HttpHandler会是MvcHandler.
11、URL Routing组件是如何与ASP.NET MVC框架组合起来的。
在第一次启动mvc程序的时候,在Application_Start函数中注册路由RegisterRoutes(RouteTable.Routes);在routes.MapRoute(…)函数中,将自定义的路由规则注册到System.Web.Routing 组件中, Route route = new Route(url, new MvcRouteHandler())
注:在处理该请求时将由 HttpApplication 类执行以下事件。希望扩展 HttpApplication 类的开发人员尤其需要注意这些事件。
-
对请求进行验证,将检查浏览器发送的信息,并确定其是否包含潜在恶意标记。有关更多信息,请参见 ValidateRequest 和脚本侵入概述。
-
如果已在 Web.config 文件的 UrlMappingsSection 节中配置了任何 URL,则执行 URL 映射。
-
引发 BeginRequest 事件。
-
引发 AuthenticateRequest 事件。
-
引发 PostAuthenticateRequest 事件。
-
引发 AuthorizeRequest 事件。
-
引发 PostAuthorizeRequest 事件。
-
引发 ResolveRequestCache 事件。
-
引发 PostResolveRequestCache 事件。
-
根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理。如果该请求针对从 Page 类派生的对象(页),并且需要对该页进行编译,则 ASP.NET 会在创建该页的实例之前对其进行编译。
-
引发 PostMapRequestHandler 事件。
-
引发 AcquireRequestState 事件。
-
引发 PostAcquireRequestState 事件。
-
引发 PreRequestHandlerExecute 事件。
-
为该请求调用合适的 IHttpHandler 类的 ProcessRequest 方法(或异步版 BeginProcessRequest)。例如,如果该请求针对某页,则当前的页实例将处理该请求。
-
引发 PostRequestHandlerExecute 事件。
-
引发 ReleaseRequestState 事件。
-
引发 PostReleaseRequestState 事件。
-
如果定义了 Filter 属性,则执行响应筛选。
-
引发 UpdateRequestCache 事件。
-
引发 PostUpdateRequestCache 事件。
-
引发 EndRequest 事件。
当我们对asp.net mvc网站发出一个请求的时候,会发生5个主要步骤:
步骤1:创建routetable 当asp.net应用程序第一次启动的时候才会发生第一步。routetable把url映射到handler。
步骤2:urlroutingmodule拦截请求 第二步在我们发起请求的时候发生。urlroutingmodule拦截了每一个请求并且创建和执行合适的handler。
步骤3:执行mvchandler mvchandler创建了控制器,并且把控制器传入controllercontext,然后执行控制器。
步骤4:执行控制器 控制器检测要执行的控制器方法,构建参数列表并且执行方法。
步骤5:调用renderview方法 大多数情况下,控制器方法调用renderview()来把内容呈现回浏览器。controller.renderview()方法把这个工作委托给某个viewengine来做。