我一直疑惑于以下问题,从客户端发出一个请求,请求到达服务器端是怎样跟iis衔接起来的,而iis又是怎样读取我发布的代码的,并返回服务器上的文件。这其中是怎样的一个处理过程。
1:当你从浏览器中输入一个地址或点击一个链接开始,你就已经发出了一个http请求(会根据请求者请求的主机头或者IP或者端口号来找到对应的站点);
2:根据http协议,当请求到达相应的主机服务器时,由服务器上的系统进程http.sys(可以理解为专门处理http请求的进程)接收;
3:http.sys接收到请求信号后,传递给应用程序池的工作者进程,即IIS进程 inetinfo.exe,注意:这时候服务器进程与IIS衔接起来了。
IIS进程可以处理一般的静态页面如.html,处理完后直接将找到的html页面返回到客户端显示;
4:如果是.aspx 或cshtml等页面,IIS不能直接处理,这时,IIS进程会加载一个叫aspnet_isapi.dll;
5:当ISAPI收到处理请求后,会启动一个ASP.NET工作进程,然后将请求信息转交给ASP.NET工作进程(ASPNET_WP.EXE),注意:这时候IIS与ASP.NET衔接起来了。接下来,控制权由ASPNET_WP掌握。
【 我们先来了解下APPDOMAIN是什么, 感觉这篇不错http://allanpie.blog.163.com/blog/static/21320410200921311273632/, 我理解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。】
6:当控制权交给ASPNET_WP进程掌握后,如果没有执行.net的环境,会先建立APPDOMAIN执行应用程序域,在APPDOMAIN建立时, ISAPIRUNTIME和HttpRuntime这两个类会作为APPDOMAIN的一部分被实例化。
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来做。
这些知识及图片都是参考下面的博文总结来的,方便查看
参考:
http://blog.csdn.net/jilate/article/details/437506
http://www.cnblogs.com/tmfc/archive/2006/08/29/489779.html
http://blog.csdn.net/virone/article/details/4531800
http://msdn.microsoft.com/zh-cn/library/ms178473%28v=VS.80%29.aspx