1、IIS服务器根据请求的文件的后缀名来肯定如何处理这个请求。例如.html,或.js,或.aspx…服务器获取所请求的页面的后缀名后,在服务器端寻找能够处理这类后缀名的应用程序,若是IIS找不到能够处理此类文件的应用程序,而且这个文件也没有受到服务器端的保护(一个受保护的例子就是App_Code中的文件,一个不受保护的例子就是你的js脚本),那么IIS就直接把这个文件返回给客户端。html
若是服务器找到了处理此类文件的应用程序,一般称为ISAPI(Internet Server Application Programe Interface,互联网服务器应用程序接口)应用程序,他实际上只是一个接口,起到一个代理的做用,它的主要工做是映射所请求的页面(文件)和与此后缀名相对应的实际的处理程序。程序员
例如全部的.aspx文件实际上都是由aspnet_isapi.dll这个程序来处理的,当IIS把对于.aspx页面的请求提交给了aspnet_isapi.dll之后,它就再也不关心这个请求随后是如何处理的了。Asp.net只是服务器(IIS)的一个组成部分而已,它是一个ISAPI扩展。web
HttpRuntime类是asp.net的一个主要入口,它有一个称做ProcessRequest的方法,这个方法以一个HttpWorkerRequest类做为参数,HttpRuntime类几乎包含着关于单个Http请求的全部信息:所请求的文件、服务器变量、QueryString、Http头信息等等。Asp.net使用这些信息来加载、运行正确的文件,而且将这个请求转换到输出流中,通常来讲,也就是HTML页面。api
当web.config文件的内容发生改变,或者.aspx文件发生变更的时候,为了可以卸载运行在同一个进程中的应用程序,而后再从新加载,Http请求被分放在相互隔离的应用程序域中。HTTP.SYS的内置驱动程序来监听来自外部的HTTP请求,在操做系统启动的时候,IIS首先在HTTP.SYS中注册本身的虚拟路径。浏览器
若是请求是一个可访问的URL,HTTP.SYS会将这个请求交给IIS工做者进程。IIS6.0中叫作w3wp.exe,IIS5.0中叫作aspnet_wp.exe。服务器
除了映射文件与其对应的处理程序外,ISAPI还须要作一些其余的工做:app
一、从HTTP.SYS中获取当前的Http请求信息,而且将这些信息保存到HttpWorkerRequest类中。asp.net
二、在相互隔离的应用程序域AppDomain中加载HttpRuntimepost
三、调用 HttpRuntime的ProcessRequest方法。url
接下来才是程序员一般编写的代码所完成的工做了,而后,IIS接收返回的数据流,并从新返还给 HTTP.SYS,最后,HTTP.SYS 再将这些数据返回给客户端浏览器。
2、当Http请求进入Asp.net RunTime之后,它的管道由托管模块(Managed Modules)和处理程序(Handlers)组成,而且由管道来处理这个Http请求。
按照图中的编号了解数据是如何流动的:
① HttpRuntime将Http请求转交给HttpApplication,HttpApplication表明着程序员建立的Web应用程序。HttpApplication建立针对此Http请求的HttpContext对象,这些HttpContext对象包含了关于此请求的诸多其余对象,主要有HttpRequest、HttpResponse、HttpSessionState等。这些对象在程序中能够经过Page类或者Context类进行访问。
② 接下来Http请求经过一系列Module,这些Module对Http请求具备彻底的控制权。这些Module能够作一些执行某个实际工做前的事情。
③ Http请求通过全部的Module以后,它会被HttpHandler处理。
④ HttpHandler处理完之后,Http请求再一次回到Module,此时Module能够作一些某个工做已经完成了以后的事情。
3、Http管道中有两个可用的接口。一个是IHttpHandler,一个是IHttpModule。经过查看“处理程序映射”,发现好多文件都交给aspnet_isapi.dll去处理了。很明显,aspnet_isapi.dll不可能对每种文件采用同一种方式处理,因此在C:、WiNDOWS\Microsoft.NET\Framework\v2.0.50727\Config\目录下web.config文件中的<httpHandlers>节点中将不一样的文件类型映射给不一样的Handler去处理,对于.aspx来讲,是由System.Web.UI.Page.HandlerFactory来处理。
1 <httpHandlers>
2
3 …… 4
5 <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
6
7 <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />
8
9 <add path="*.asmx" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" />
10
11 <add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
12
13 <add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
14
15 <add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
16
17 <add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
18
19 <add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
20
21 …… 22
23 <add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />
24
25 <add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="True" />
26
27 </httpHandlers>
.Net Framework在处理Http请求时采用默认Handler,而若是要操控一个Http请求,就须要实现IHTTPHandler接口,而实现IHttpHandler接口的类就是通常处理程序。
1 // 摘要: 2
3 // 定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
4
5 public interface IHttpHandler 6
7 { 8
9 bool IsReusable { get; } 10
11 void ProcessRequest(HttpContext context); 12
13 }
该接口中包含一个属性和一个方法,其中ProcessRequest方法中的代码是处理请求的主要代码。IsReusable属性,该值指示其余请求是否可使用IHttpHandler实例,也就是说后继的Http请求是否是能够继续使用实现了该接口的类的实例,为true时能够,不然不能够。下面是一个自定义的处理程序:
1 public class Handler1 : IHttpHandler 2 { 3 public void ProcessRequest(HttpContext context) 4 { 5 //处理请求的代码
6 } 7 public bool IsReusable 8 { 9 get
10 { 11 return true; 12 } 13 } 14 }
建立一个自定义的HttpHandler后,为了让它可以处理某些HTTP请求,还须要将它注册到web.config中:
1 <httpHandlers>
2
3 <add verb="*" path="*.jpg" type="Test_js.Handler1"/>
4
5 </httpHandlers>
path:指的是请求的文件名称,可使用通配符扩大范围,也能够明确指定这个Handler仅用于处理某个特定的文件的请求。
verb:指的是请求此文件的方式,可使post或get,用*表明全部的访问方式。
type:程序集.类名
IHttpFactory接口概述:
1 public interface IHttpHandlerFactory 2
3 { 4
5 IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated); 6
7 void ReleaseHandler(IHttpHandler handler); 8
9 }
GetHandler方法中的参数介绍:
context:System.Web.HttpContext 类的实例,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session和 Server)的引用。
requestType:客户端使用的 HTTP 数据传输方法(GET 或 POST)。
url:所请求资源的 System.Web.HttpRequest.RawUrl。
pathTranslated:所请求资源的 System.Web.HttpRequest.PhysicalApplicationPath。
该接口中定义了2个方法,GetHandler方法在请求开始的时候被调用,而ReleaseHandler在请求结束,全部的Handler都不在须要的时候被调用。
一个HandlerFactory能够处理N个HttpHandler,何时该处理什么HttpHandler就在这里的处理逻辑中实现。
何时使用IHttpHandlerFactory:
一、在一个项目中须要使用不少IHttpHandler的时候,并且对这些IHttpHandler判断都重复作一个一样的前期处理。
二、从部署和松散耦合考虑,若是你的web application足够大,你就要考虑在更换HttpHandler处理类的时候该不应去改动Web.config的配置,这种改动将会从新启动整个app,对于一些系统而言这是不能够随便进行的。这个时候,统一一个入口的IHttpHandlerFactory很重要,这个入口相对不变,而IHttpHandler实现能够经过外挂自定义的xml文件来实现松散耦合,运用一些反射什么的就能够实现了。
3、HttpModule是实现了IHttpModule接口的程序集,HttpModule的做用是与应用程序事件相关的。
1 public interface IHttpModule 2
3 { 4
5 void Dispose(); 6
7 void Init(HttpApplication context); 8
9 }
Init()方法:这个方法接受一个HttpApplication对象,HttpApplication表明了当前的应用程序,在这个方法中注册对事件进行注册。
Dispose():它能够在进行垃圾回收以前进行一些清理工做。
经过在Http请求管道中注册指望对应用程序事件做出反应的方法,在相应的事件触发的时候,便会调用HttpModule注册了的方法,实际的工做在这些方法中执行。
自定义的HttpModule须要咱们本身在web.config文件中对其进行注册:
1 <system.webServer>
2 <modules>
3 <add name="MyModule" type="WebApplication1.ModuleDemo,WebApplication1"/>
4 </modules>
5 </system.webServer>
整个过程:
一、当站点第一个资源被访问的时候,Asp.Net会建立HttpApplication类的实例,它表明着站点应用程序,同时会建立全部在Web.Config中注册过的Module实例。
二、在建立Module实例的时候会调用Module的Init()方法。
三、在Init()方法内,对想要做出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法须要另写)。
四、HttpApplication在其应用程序周期中触发各种事件。
五、触发事件的时候调用Module在其Init()方法中注册过的方法