概念:ISAPI 服务器扩展是可以被 HTTP 服务器加载和调用的 DLL。
1.当asp.net页面发起请求时,IIS收到请求会根据请求页面的后缀名,交给相应的ASP.NET ISAPI做处理,
2.ASP.NET ISAPI安排aspnet_wp.exe处理请求,并监视aspnet_wp.exe(w3wp.exe iis 6)进程的执行情况。
3.aspnet_wp.exe的主要任务是将请求交给一系列称为的 HTTP 管道的托管对象
恰当的比喻:
如果把ASP.NET ISAPI比做销售经理,那aspnet_wp.exe就是生产经理,而HTTP 管道就是生产的流水线。
负责流水线的小组就是HttpRuntime,生产经理aspnet_wp.exe会将订单(HTTP请求)交给HttpRuntime小组的工作人员ProcessRequest(HttpWorkerRequest wr),HttpRuntime根据内部的分工,最终由ProcessRequestInternal(HttpWorkerRequest wr)在流水线上进行生产,所以ProcessRequestInternal(HttpWorkerRequest wr)是我们分析的重点。
ProcessRequestInternal的主要工作是:
1. 创建HttpContext实例
2. 对第一次请求进行初始化(EnsureFirstRequestInit)。
3. 创建HttpWriter实例。
4. 通过调用HttpApplicationFactory.GetApplicationInstance创建HttpApplication实例。
创建HttpApplication实例之后就是调用实例的InitInternal方法。
InitInternal方法主要功能如下:
4.1 InitModules():根据Web.Config的设置,创建相应的HttpModules。
4.2 HookupEventHandlersForAppplicationAndModules:根据发生的事件,调用HttpApplication实例中相应的事件处理函数。
4.3创建很多实现IExecutionStep接口的类的实例并添加到当前HttpApplication实例的_execSteps中,等待回调时执行。
5. 调用HttpApplication实例的BeginProcessRequest异步处理请求。
详见:http://www.cnblogs.com/aaa6818162/archive/2009/11/13/1602333.html
1,当接收到一个HTTP请求
2,通过iis中的isapi从 http.sys中获取当前的htttp的请求信息,并且将这些信息保存到 HttpWorkerRequest 类中
3,在相互隔离的应用程序域AppDomain中加载HttpRuntime。 调用 HttpRuntime的ProcessRequest方法( 方法参数HttpWorkerRequest )
4,Http请求进入 HttpRuntime以后
5. HttpRuntime将Http请求转交给 HttpApplication,HttpApplication代表着程序员创建的Web应用程序。
HttpApplication创建针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其他对象,主要是HttpRequest、HttpResponse、HttpSessionState等。这些对象在程序中可以通过Page类或者Context类进行访问。、
6. 接下来Http请求通过一系列Module,这些Module对Http请求具有完全的控制权。
这些Module可以做一些执行某个实际工作前的事情。
7. Http请求经过所有的Module之后,它会被HttpHandler处理。
在这一步,执行实际的一些操作,通常也就是.aspx页面所完成的业务逻辑。
public class Page : TemplateControl, IHttpHandler{
// 代码省略
}
可以看到,Page类实现了IHttpHandler接口,HttpHandler也是Http请求处理的最底层。
8.HttpHandler处理完以后,Http请求再一次回到Module,此时Module可以做一些某个工作已经完成了之后的事情。
9.然后,IIS 接收返回的数据流,并重新返还给 HTTP.SYS,
10最后,HTTP.SYS 再将这些数据返回给客户端浏览器。
在创建好HttpApplication后注意的一些事情
HttpModule和HttpHandler两者都是在HttpApplication.Init()函数调用的一部分中被载入并附加到调用链上
//在添加所有事件处理程序模块之后执行自定义初始化代码。
HttpApplication public virtual void Init();
总的来说
1先通过 httpapplication的initinternal方法,初始化各个module
2再通过httpapplication下的applicationstepmanager的buildestep方法 (按顺序建立各个步骤)
3httpapplication的beginprocessrequest方法执行建立起来咯各个步骤,即触发httpapplication的生命周期
httphandel和httpmodel的执行关系
表 1:HttpApplication 对象激发的事件
事件 | 备注 |
BeginRequest |
在请求处理开始之前激发 |
AuthenticateRequest |
验证调用方的身份 |
AuthorizeRequest |
执行访问检查 |
ResolveRequestCache |
从缓存中获取响应 |
AcquireRequestState |
加载会话状态 |
PreRequestHandlerExecute |
在请求即将发送到处理程序对象之前激发 |
PostRequestHandlerExecute |
在请求刚刚发送到处理程序对象之后激发 |
ReleaseRequestState |
存储会话状态 |
UpdateRequestCache |
更新响应缓存 |
EndRequest |
在处理结束后激发 |
PreSendRequestHeaders |
在发送缓存的响应标头之前激发 |
PreSendRequestContent |
在发送缓存的响应正文之前激发 |
注意:HTTP 处理程序(HttpHandler)在 PreRequestHandlerExecute 和 PostRequestHandlerExecute 事件之间执行。
HttpApplication是HttpRuntime所创建的吗? 并不是,HttpRuntime只是向HttpApplicationFactory提出请求,要求返回一个HttpApplication对象。HttpApplicationFactory在接收到请求后,会先检查是否有已经存在并空闲的对象,如果有就取出一个HttpApplication对象返回给HttpRuntime,如果没有的话,则要创建一个HttpApplication对象给HttpRunTime。
关于HttpApplication这个类的方法的实现,就不再一一解释,需要了解的,在类里面写上一个HttpApplication单词,然后右键选择“转到定义“,就可以看到里面的元数据了。
参考备注:
ASP。NET的设计思想 http://www.cnblogs.com/aaa6818162/archive/2009/10/30/1592886.html#1688909
HttpApplication的认识与加深理解 http://www.cnblogs.com/whtydn/archive/2009/10/16/1584584.html
asp.net原理 《重要》 http://www.cnblogs.com/aaa6818162/archive/2009/11/11/1600987.html