HTTP 处理程序和 HTTP 模块概述

Visual Studio 2010

更新:2007 年 11 月

ASP.NET HTTP 处理程序是响应对 ASP.NET Web 应用程序的请求而运行的过程(通常称为“终结点”)。最常用的处理程序是处理 .aspx 文件的 ASP.NET 页处理程序。用户请求 .aspx 文件时,页通过页处理程序来处理请求。您可以创建自己的 HTTP 处理程序将自定义输出呈现给浏览器。

HTTP 模块是一个在每次针对应用程序发出请求时调用的程序集。HTTP 模块作为 ASP.NET 请求管道的一部分调用,它们能够在整个请求过程中访问生命周期事件。HTTP 模块使您可以检查传入和传出的请求并根据该请求进行操作。

本主题包括:

自定义 HTTP 处理程序通常具有以下用途:

  • RSS 源 若要为网站创建 RSS 源,可以创建一个可发出 RSS 格式 XML 的处理程序。然后可以将文件扩展名(如 .rss)绑定到此自定义处理程序。当用户向站点发送以 .rss 结尾的请求时,ASP.NET 将调用您的处理程序来处理请求。

  • 图像服务器 如果希望 Web 应用程序能够提供不同大小的图像,可以编写一个自定义处理程序来调整图像大小,然后将调整后的图像作为处理程序的响应发送给用户。

HTTP 模块通常具有以下用途:

  • 安全 因为您可以检查传入的请求,所以 HTTP 模块可以在调用请求页、XML Web services 或处理程序之前执行自定义的身份验证或其他安全检查。在以集成模式运行的 Internet 信息服务 (IIS) 7.0 中,可以将 Forms 身份验证扩展到应用程序中的所有内容类型。

  • 统计信息和日志记录 因为 HTTP 模块是在每次请求时调用的,所以,您可以将请求统计信息和日志信息收集到一个集中的模块中,而不是收集到各页中。

  • 自定义的页眉或页脚 因为您可以修改传出响应,所以可以在每一个页面或 XML Web services 响应中插入内容,如自定义的标头信息。

返回页首

HTTP 处理程序和模块功能包括:

  • IHttpHandlerIHttpModule 接口是开发处理程序和模块的起始点。

  • IHttpAsyncHandler 接口是开发异步处理程序的起始点。

  • 自定义处理程序和模块源代码可以放在应用程序的 App_Code 文件夹中,也可以在应用程序的 Bin 文件夹中编译和存放。

  • 为在 IIS 6.0 中使用而开发的处理程序和模块经过少许更改或不经更改即可在 IIS 7.0 中使用。有关更多信息,请参见将 ASP.NET 应用程序从 IIS 6.0 迁移到 IIS 7.0

  • 模块可以订阅多种请求管道通知。模块可以接收 HttpApplication 对象的事件通知。

  • 在 IIS 7.0 中,请求管道与 Web 服务器请求管道集成在一起。HTTP 模块可用于对 Web 服务器的任何请求,而不仅仅是 ASP.NET 请求。

返回页首

HTTP 处理程序

ASP.NET HTTP 处理程序是响应对 ASP.NET Web 应用程序的请求而运行的过程。最常用的处理程序是处理 .aspx 文件的 ASP.NET 页处理程序。用户请求 .aspx 文件时,通过页处理程序来处理请求。

ASP.NET 页处理程序仅仅是一种类型的处理程序。ASP.NET 包括其他几种内置的处理程序,例如用于 .asmx 文件的 Web 服务处理程序。

ASP.NET 中的内置 HTTP 处理程序

ASP.NET 根据文件扩展名将 HTTP 请求映射到 HTTP 处理程序。每个 HTTP 处理程序都可以处理应用程序中的单个 HTTP URL 或 URL 扩展名组。ASP.NET 包括几种内置的 HTTP 处理程序,如下表所列。

处理程序

说明

ASP.NET 页处理程序 (*.aspx)

用于所有 ASP.NET 页的默认 HTTP 处理程序。

Web 服务处理程序 (*.asmx)

在 ASP.NET 中作为 .asmx 文件创建的 Web 服务页的默认 HTTP 处理程序。

泛型 Web 处理程序 (*.ashx)

不含 UI 和包括 @ WebHandler 指令的所有 Web 处理程序的默认 HTTP 处理程序。

跟踪处理程序 (trace.axd)

显示当前页跟踪信息的处理程序。有关详细信息,请参见 如何:使用跟踪查看器查看 ASP.NET 跟踪信息

创建自定义 HTTP 处理程序

若要创建自定义 HTTP 处理程序,请创建实现 IHttpHandler 接口的类来创建一个同步处理程序。或者,可以实现 IHttpAsyncHandler 来创建一个异步处理程序。两种处理程序接口都要求您实现 IsReusable 属性和 ProcessRequest 方法。IsReusable 属性指定 IHttpHandlerFactory 对象(实际调用适当处理程序的对象)是否可以将处理程序放置在池中,并且重新使用它以提高性能。如果处理程序不能放在池中,则在每次需要处理程序时工厂都必须创建处理程序的新实例。

ProcessRequest 方法负责处理单个 HTTP 请求。在此方法中,将编写生成处理程序输出的代码。

HTTP 处理程序有权访问应用程序上下文。其中包括请求用户的标识(如果已知)、应用程序状态和会话信息。当请求 HTTP 处理程序时,ASP.NET 将调用相应处理程序的 ProcessRequest 方法。您在处理程序的 ProcessRequest 方法中编写的代码将创建一个响应,此响应随后发送回请求浏览器。

映射文件扩展名

当创建一个类文件作为 HTTP 处理程序时,该处理程序可以响应尚未在 IIS 和 ASP.NET 中映射的任何文件扩展名。例如,如果要创建用于生成 RSS 源的 HTTP 处理程序,则可以将您的处理程序映射到 .rss 文件扩展名。为了使 ASP.NET 了解为您的自定义文件扩展名使用哪个处理程序,在 IIS 中必须将该扩展名映射到 ASP.NET。然后在应用程序中必须将该扩展名映射到自定义处理程序。

默认情况下,ASP.NET 将文件扩展名 .ashx 映射到 HTTP 处理程序。如果将 @ WebHandler 指令添加到某个类文件,则 ASP.NET 会自动将 .ashx 文件扩展名映射到默认的 HTTP 处理程序。这与在使用 @ Page 指令时,ASP.NET 将 .aspx 文件扩展名映射到 ASP.NET 页处理程序的方式类似。因此,如果您创建具有文件扩展名 .ashx 的 HTTP 处理程序类,该处理程序将自动注册到 IIS 和 ASP.NET。

如果要为处理程序创建自定义文件扩展名,则必须使用 IIS 和 ASP.NET 显式注册该扩展名。不使用 .ashx 文件扩展名的优点在于处理程序可为不同的扩展名映射重用。例如,在一个应用程序中,自定义处理程序可能响应以 .rss 结尾的请求。在另一个应用程序中,该自定义处理程序可能响应以 .feed 结尾的请求。再举一例,该处理程序可能映射到同一应用程序中的两个文件扩展名,但可能基于扩展名创建两个不同的响应。

在 IIS 7.0 中注册处理程序的自定义文件扩展名的过程与在早期版本的 IIS 中不同。有关更多信息,请参见如何:注册 HTTP 处理程序如何:在 IIS 中配置 HTTP 处理程序扩展名

异步和同步 HTTP 处理程序

HTTP 处理程序可以是同步的也可以是异步的。同步处理程序在完成对为其调用该处理程序的 HTTP 请求的处理后才会返回。异步处理程序运行进程的行为与向用户发送响应无关。当您必须启动一个可能耗费很长时间的应用程序进程,而用户又无需等候进程完成以便从服务器接收响应时,异步处理程序非常有用。

使用异步 HTTP 处理程序可以启动一个外部进程,如对远程服务器的方法调用。该处理程序可以继续处理,而不必等待外部进程结束。在异步 HTTP 处理程序正在处理时,ASP.NET 将通常用于外部进程的线程放回线程池中,直到处理程序收到来自外部进程的回调。由于只能同时执行有限数量的线程,因此这样可以避免阻止线程并改善性能。如果许多用户都在请求依赖于外部进程的同步 HTTP 处理程序,那么操作系统可能用完所有线程,因为大量线程被阻止,正在等待外部进程。

在创建异步处理程序时,必须实现 IHttpAsyncHandler 接口。为了启动处理单个 HTTP 请求的异步调用,还必须实现 BeginProcessRequest 方法。此外,必须实现 EndProcessRequest 方法,以便在进程结束时运行清理代码。

自定义 IHttpHandlerFactory 类

IHttpHandlerFactory 类接收请求并负责向相应的 HTTP 处理程序转发请求。您可以通过创建一个实现了 IHttpHandlerFactory 接口的类来创建自定义 HTTP 处理程序工厂。自定义处理程序工厂通过创建不同的基于运行时条件的处理程序,使您可以更好地控制对 HTTP 请求的处理方式。例如,使用自定义 HTTP 处理程序工厂,可以在 HTTP 请求方法为 PUT 时为某个文件类型实例化一个 HTTP 处理程序,而在该方法为 GET 时实例化另一个 HTTP 处理程序。

若要为处理程序工厂注册自定义扩展名,请遵循为处理程序注册自定义扩展名的步骤。有关创建和注册处理程序工厂的示例,请参见演练:创建和注册 HTTP 处理程序工厂

HTTP 模块

HTTP 模块是一个在每次针对应用程序发出请求时调用的程序集。HTTP 模块作为请求管道的一部分调用,它们能够在整个请求过程中访问生命周期事件。因此,HTTP 模块使您可以检查传入的请求并根据该请求进行操作。它们还使您可以检查传出的响应并修改它。

在 IIS 6.0 中,ASP.NET 请求管道与 Web 服务器请求管道分离。在 IIS 7.0 中,ASP.NET 请求管道和 Web 服务器请求管道可以集成到通用请求管道中。在 IIS 7.0 中,此操作称为“集成”模式。对于 ASP.NET 开发人员,统一的管道有多个优点。例如,它使托管代码模块可以接收所有请求的管道通知,即使这些请求不是针对 ASP.NET 资源。但是,如果需要,可以在经典模式下运行 IIS 7.0,该模式模拟在 IIS 6.0 中运行 ASP.NET。有关更多信息,请参见 IIS 7.0 的 ASP.NET 应用程序生命周期概述

ASP.NET HTTP 模块针对所有请求调用,这与 ISAPI 筛选器类似。但是它们是用托管代码编写的,而且可以与 ASP.NET 应用程序的生命周期完全集成。可以将自定义模块源代码放在应用程序的 App_Code 文件夹中,也可以将经过编译的自定义模块作为程序集放在应用程序的 Bin 文件夹中。

ASP.NET 使用模块来实现各个应用程序功能,其中包括 Forms 身份验证、缓存、会话状态和客户端脚本服务。在每种情况下,如果这些服务处于启用状态,模块会作为请求的一部分调用,并执行在任何单一页请求范围之外的任务。模块可以使用应用程序事件,可能会引发可在 Global.asax 文件中处理的事件。有关应用程序事件的更多信息,请参见 IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述IIS 7.0 的 ASP.NET 应用程序生命周期概述

Bb398986.alert_note(zh-cn,VS.100).gif说明:

HTTP 模块不同于 HTTP 处理程序。HTTP 处理程序通过文件扩展名或文件扩展名系列来识别请求,并返回对请求的响应。相反,HTTP 模块是为所有请求和响应调用的。它订阅请求管道中的事件通知,并使您可以运行已注册事件处理程序中的代码。使用模块的任务对于应用程序和针对应用程序中的资源的所有请求都是通用的。

HTTP 模块的工作方式

模块必须经过注册才能从请求管道接收通知。注册 HTTP 模块的最常用方法是在应用程序的 Web.config 文件中进行注册。在 IIS 7.0 中,统一的请求管道使您还可以通过其他方式注册模块,其中包括通过 IIS 管理器和 Appcmd.exe 命令行工具。有关更多信息,请参见 Configuring Handler Mappings in IIS 7.0(在 IIS 7.0 中配置处理程序映射)和 Start Appcmd.exe(启动 Appcmd.exe)。

当 ASP.NET 创建表示您的应用程序的 HttpApplication 类的实例时,将创建已注册的任何模块的实例。在创建模块时,将调用它的 Init 方法,并且模块会自行初始化。有关更多信息,请参见 IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述IIS 7.0 的 ASP.NET 应用程序生命周期概述

在模块的 Init 方法中,可以订阅各种应用程序事件(如 BeginRequestEndRequest),这可以通过将事件绑定到模块中的方法来完成。

Bb398986.alert_note(zh-cn,VS.100).gif说明:

对于在 IIS 7.0 集成管道中运行的模块,应该在 Init 方法中注册事件处理程序。

当这些应用程序事件被引发时,将调用模块中的相应方法。该方法可以执行所需的任何逻辑,如检查身份验证或记录请求信息。在事件处理过程中,模块能够访问当前请求的 Context 属性。这使您可以将请求重定向到其他页、修改请求或者执行任何其他请求操作。例如,如果模块检查身份验证,则在凭据不正确的情况下,模块可能重定向到登录页或错误页。否则,当模块的事件处理程序完成运行时,ASP.NET 会调用管道中的下一个进程。这可能是另一个模块,也可能是用于该请求的 HTTP 处理程序(如 .aspx 文件)。

HTTP 模块与 Global.asax 文件

可以在应用程序的 Global.asax 文件中实现模块的许多功能,这使您可以响应应用程序事件。但是,模块相对于 Global.asax 文件具有如下优点:模块可以进行封装,因此可以在创建一次后在许多不同的应用程序中使用。通过将它们添加到全局程序集缓存并将它们注册到 Machine.config 文件中,可以跨应用程序重新使用它们。有关更多信息,请参见全局程序集缓存

Bb398986.alert_note(zh-cn,VS.100).gif说明:

在 IIS 7.0 中,集成管道使托管模块可以订阅所有请求的管道通知,而不仅仅是对 ASP.NET 资源的请求。Global.asax 文件中的事件处理程序仅为请求应用程序的资源过程中的通知调用。可以显式指定集成模式下的自定义模块的作用范围,以只接收针对应用程序的请求的事件通知。否则,自定义模块将接收对应用程序的所有请求的事件通知。如果 modules 部分的 add 元素的 precondition 属性设置为“managedHandler”,则模块的作用范围是应用程序。

使用 Global.asax 文件的好处在于可以处理其他已注册事件,如 Session_StartSession_End。此外,Global.asax 文件还允许您实例化可在整个应用程序中使用的全局对象。

当您必须创建依赖应用程序事件的代码,并且符合以下条件时,都应该使用模块:

  • 希望在其他应用程序中重用该模块。

  • 希望避免将复杂代码放在 Global.asax 文件中。

  • 该模块应用于管道中的所有请求(仅限 IIS 7.0 集成模式)。

当您必须创建依赖应用程序事件的代码并且不需要跨应用程序重用代码时,应该将代码添加到 Global.asax 文件中。当必须订阅对于模块不可用的事件(如 Session_Start)时,也可以使用 Global.asax 文件。

创建 HTTP 模块

编写 HTTP 模块的一般过程如下:

有关如何将模块从正在运行于 IIS 6.0 或更早版本 IIS 的应用程序移到运行于 IIS 7.0 的应用程序,请参见将 ASP.NET 应用程序从 IIS 6.0 迁移到 IIS 7.0

返回页首

下表列出了 HTTP 模块和 HTTP 处理程序的关键服务器类。

说明

IHttpModule

用于通过以下方法来创建自定义 HTTP 模块:实现接口,然后在 Web.config 文件中注册模块。

IHttpHandler

用于通过创建实现接口的类来创建自定义同步 HTTP 处理程序。

IHttpAsyncHandler

用于通过创建实现接口的类来创建自定义、异步 HTTP 处理程序。

返回页首

显示: