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 类在处理请求时执行:

  1. 验证请求,它检查浏览器发送的信息并确定它是否包含潜在的恶意标记。
  2. 如果在 Web.config 文件的 UrlMappingsSection 部分中配置了任何 URL,则执行 URL 映射。
  3. 引发 BeginRequest 事件。
  4. 引发 AuthenticateRequest 事件。
  5. 引发 PostAuthenticateRequest 事件。
  6. 引发 AuthorizeRequest 事件。
  7. 引发 PostAuthorizeRequest 事件。
  8. 引发 ResolveRequestCache 事件。
  9. 引发 PostResolveRequestCache 事件。
  10. 引发 MapRequestHandler 事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,例如 IIS 7.0 StaticFileModule,也可以是托管代码模块,例如 PageHandlerFactory 类(处理 .aspx 文件)。
  11. 引发 PostMapRequestHandler 事件。
  12. 引发 AcquireRequestState 事件。
  13. 引发 PostAcquireRequestState 事件。
  14. 引发 PreRequestHandlerExecute 事件。
  15. 为请求调用相应 IHttpHandler 类的 ProcessRequest 方法(或异步版本 IHttpAsyncHandler.BeginProcessRequest)。例如,如果请求是针对某个页面的,则当前页面实例会处理该请求。
  16. 引发 PostRequestHandlerExecute 事件。
  17. 引发 ReleaseRequestState 事件。
  18. 引发 PostReleaseRequestState 事件。
  19. 如果定义了 Filter 属性,则执行响应过滤。
  20. 引发 UpdateRequestCache 事件。
  21. 引发 PostUpdateRequestCache 事件。
  22. 引发 LogRequest 事件。
  23. 引发 PostLogRequest 事件。
  24. 引发 EndRequest 事件。
  25. 引发 PreSendRequestHeaders 事件。
  26. 引发 PreSendRequestContent 事件。

  仅当应用程序在 IIS 7.0 和 .NET Framework 3.0 或更高版本中以集成模式运行时,才支持 MapRequestHandler、LogRequest 和 PostLogRequest 事件。

六、事件说明

  1. BeginRequest. 接收到新的HTTP请求的时。
  2. AuthenticateRequest. 订阅此事件,以执行身份验证。
  3. PostAuthenticateRequest.
  4. AuthorizeRequest. 订阅此事件,以检查经过身份验证的用户是否有权访问所请求的资源。
  5. PostAuthorizeRequest.
  6. ResolveRequestCache. 订阅此事件,以检查对该请求的响应是否存在于缓存中,并返回它而不是继续执行。这依赖于应用程序的输出缓存是怎样设置的。
  7. PostResolveRequestCache.
  8. MapRequestHandler. 订阅此事件,以确定请求 的 handler。
  9. PostMapRequestHandler.
  10. AcquireRequestState. 订阅此事件,以获取执行请求所需的状态。ASP.NET Session State 和 Profile 模块需要这些数据。
  11. PostAcquireRequestState.
  12. PreExecuteRequestHandler. 执行 handler 前发生,任何任务都会被执行。
  13. ExecuteRequestHandler. 执行 handler。
  14. PostRequestHandlerExecute handler 执行完毕时发生。
  15. ReleaseRequestState. 订阅此事件,以更改请求状态,并在此处清理状态。ASP.NET Session State and Profile 模块在此事件中进行清理。
  16. PostReleaseRequestState.
  17. UpdateRequestCache. 订阅此事件,以缓存响应,以备将来使用。这依赖于应用程序的输出缓存是怎样设置的。
  18. PostUpdateRequestCache.
  19. LogRequest. 订阅此事件,以记录请求的结果,即使发生错误也能保证执行此事件。
  20. PostLogRequest.
  21. EndRequest. 订阅此事件,以进行最终请求清理,并保证即使发生错误也会执行此事件。
  22. PreSendRequestHeaders 向客户端发送 HTTP 标头之前发生
  23. PreSendRequestContent 向客户端发送内容之前发生。
  24. Error 当引发未经处理的异常时发生。
  25. Disposed 在释放应用程序时发生。

  本文大部分内容来自:ASP.NET Application Life Cycle Overview for IIS 7.0

posted @ 2021-06-28 10:40  误会馋  阅读(112)  评论(0编辑  收藏  举报