HttpModule订阅管道事件
一、IIS 7 及以上集成模式请求处理
1.流程
在 IIS 7.0 的集成模式下,一个统一的管道处理所有请求。当集成管道接收到请求时,请求会通过“所有请求”都会通过的阶段。
2.代码中枚举
这些阶段由 RequestNotification 枚举表示。
二、接收到第一个请求
当IIS统一管道接收到应用程序【注:安装在IIS内网站应用程序,下同】中任何资源的第一个请求时,会创建一个 ApplicationManager 类的实例,该实例就是处理请求的 application domain。application domain为【应用程序】之间提供全局变量隔离,并使每个【应用程序】能够单独卸载。 在application domain中( 即在ApplicationManager 类的实例中),创建了一个 HostingEnvironment 类的实例,它提供了对有关【应用程序】信息的访问,例如,存储应用程序的文件夹的名称。
在第一个请求期间,如果需要,将编译【应用程序】中的顶级项目,其中包括 App_Code 文件夹中的应用程序代码。 您可以在 App_Code 文件夹中包含自定义模块和处理程序。
三、为每个请求创建响应
在创建application domain并实例化 HostingEnvironment 对象后,将创建并初始化 HttpContext、HttpRequest 和 HttpResponse 等应用程序对象。
1.HttpContext 类包含当前请求的特定对象,例如 HttpRequest 和 HttpResponse 对象。HttpContext 对象还包含有两个属性 IsPostNotification 和 CurrentNotification,用于处理多个 HttpApplication 事件被一起订阅的情况。
(1)HttpRequest 对象包含有关当前请求的信息,其中包括 cookie 和浏览器信息。HttpRequest 对象的 Headers 和 ServerVariables 属性是可写的。
(2)HttpResponse 对象包含发送到客户端的响应,其中包括所有呈现的输出和 cookie。HttpResponse 对象包含 Headers 属性,提供对响应的响应标头的访问。
四、HttpApplication 对象
一个 HttpApplication 对象被分配给请求:
初始化所有应用程序对象后,通过创建 HttpApplication 类的实例来启动【应用程序】。如果【应用程序】具有 Global.asax 文件,则 ASP.NET 会创建从 HttpApplication 类派生的 Global.asax 类的实例,然后使用派生类来表示应用程序。
为了最大限度地提高性能,HttpApplication 实例可能会被重复用于多个请求。
加载哪些 ASP.NET 模块(例如 SessionStateModule)取决于【应用程序】从父应用程序继承的托管代码模块,它还取决于在【应用程序】的 Web.config 文件的配置部分中配置了哪些模块。
五、请求由 HttpApplication 管道处理
HttpApplication 管道的“请求处理步骤” ,以“事件”的方式暴露出来,供页面开发人员或自定义模块开发人员使用。
这些事件对于页面开发人员很有用,如果他们希望“在引发关键事件时”运行某一程序代码。
如果您正在开发自定义模块,并且您希望针对所有请求调用该模块,它们也很有用。 自定义模块实现 IHttpModule 接口。 在 IIS 7.0 的集成模式下,您必须在模块的 Init 方法中注册事件处理程序。
以下任务由 HttpApplication 类在处理请求时执行:
- 验证请求,它检查浏览器发送的信息并确定它是否包含潜在的恶意标记。
- 如果在 Web.config 文件的 UrlMappingsSection 部分中配置了任何 URL,则执行 URL 映射。
- 引发 BeginRequest 事件。
- 引发 AuthenticateRequest 事件。
- 引发 PostAuthenticateRequest 事件。
- 引发 AuthorizeRequest 事件。
- 引发 PostAuthorizeRequest 事件。
- 引发 ResolveRequestCache 事件。
- 引发 PostResolveRequestCache 事件。
- 引发 MapRequestHandler 事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,例如 IIS 7.0 StaticFileModule,也可以是托管代码模块,例如 PageHandlerFactory 类(处理 .aspx 文件)。
- 引发 PostMapRequestHandler 事件。
- 引发 AcquireRequestState 事件。
- 引发 PostAcquireRequestState 事件。
- 引发 PreRequestHandlerExecute 事件。
- 为请求调用相应 IHttpHandler 类的 ProcessRequest 方法(或异步版本 IHttpAsyncHandler.BeginProcessRequest)。例如,如果请求是针对某个页面的,则当前页面实例会处理该请求。
- 引发 PostRequestHandlerExecute 事件。
- 引发 ReleaseRequestState 事件。
- 引发 PostReleaseRequestState 事件。
- 如果定义了 Filter 属性,则执行响应过滤。
- 引发 UpdateRequestCache 事件。
- 引发 PostUpdateRequestCache 事件。
- 引发 LogRequest 事件。
- 引发 PostLogRequest 事件。
- 引发 EndRequest 事件。
- 引发 PreSendRequestHeaders 事件。
- 引发 PreSendRequestContent 事件。
仅当应用程序在 IIS 7.0 和 .NET Framework 3.0 或更高版本中以集成模式运行时,才支持 MapRequestHandler、LogRequest 和 PostLogRequest 事件。
六、事件说明
- BeginRequest. 接收到新的HTTP请求的时。
- AuthenticateRequest. 订阅此事件,以执行身份验证。
- PostAuthenticateRequest.
- AuthorizeRequest. 订阅此事件,以检查经过身份验证的用户是否有权访问所请求的资源。
- PostAuthorizeRequest.
- ResolveRequestCache. 订阅此事件,以检查对该请求的响应是否存在于缓存中,并返回它而不是继续执行。这依赖于应用程序的输出缓存是怎样设置的。
- PostResolveRequestCache.
- MapRequestHandler. 订阅此事件,以确定请求 的 handler。
- PostMapRequestHandler.
- AcquireRequestState. 订阅此事件,以获取执行请求所需的状态。ASP.NET Session State 和 Profile 模块需要这些数据。
- PostAcquireRequestState.
- PreExecuteRequestHandler. 执行 handler 前发生,任何任务都会被执行。
- ExecuteRequestHandler. 执行 handler。
- PostRequestHandlerExecute handler 执行完毕时发生。
- ReleaseRequestState. 订阅此事件,以更改请求状态,并在此处清理状态。ASP.NET Session State and Profile 模块在此事件中进行清理。
- PostReleaseRequestState.
- UpdateRequestCache. 订阅此事件,以缓存响应,以备将来使用。这依赖于应用程序的输出缓存是怎样设置的。
- PostUpdateRequestCache.
- LogRequest. 订阅此事件,以记录请求的结果,即使发生错误也能保证执行此事件。
- PostLogRequest.
- EndRequest. 订阅此事件,以进行最终请求清理,并保证即使发生错误也会执行此事件。
- PreSendRequestHeaders 向客户端发送 HTTP 标头之前发生
- PreSendRequestContent 向客户端发送内容之前发生。
- Error 当引发未经处理的异常时发生。
- Disposed 在释放应用程序时发生。
本文大部分内容来自:ASP.NET Application Life Cycle Overview for IIS 7.0