IHttpModule 接口

  名称 说明
公共方法 Dispose Disposes of the resources (other than memory) used by the module that implements IHttpModule.
公共方法 Init Initializes a module and prepares it to handle requests.
IHttpModule接口只有两个方法。

void Init(HttpApplication app);

void Dispose();

Init方法接受一个服务该请求的HttpApplication对象的引用。使用该引用可以连接到系统事件。HttpApplication对象也有一个称为Context的对象,该对象提供对ASP.NET应用程序的内在属性的引用。这样,我们就可以访问Response, Request, Session等。

表2.5列出了HTTP模块监听和处理的事件。

表2.5  HttpApplication事件

事  件

描    述

AcquireRequestState,

PostAcquireRequestState

当实际服务请求的处理程序获得与该请求关联的状态信息时发生。ASP.NET 1.x不支持PostAcquireRequestState事件

AuthenticateRequest,

PostAuthenticateRequest

当一个安全模块已经建立用户的身份时发生。ASP.NET 1.x不支持PostAuthenticateRequest事件

AuthorizeRequest,

PostAuthorizeRequest

当一个安全模块已经验证用户授权时发生。ASP.NET 1.x不支持PostAuthorizeRequest事件

BeginRequest

HTTP管道一开始处理请求就发出该事件

Disposed

由于调用了Dispose,HttpApplication对象被处置时发出该事件。

EndRequest

作为HTTP管道执行链的最后一个事件发出

Error

抛出一个未处理的异常时发生

PostMapRequestHandler

当服务请求的HTTP处理程序被找到时发出。ASP.NET 1.x不支持该事件

PostRequestHandlerExecute

当所选的HTTP处理程序完成执行时发出该事件。这时已经生成响应文本

PreRequestHandlerExecute

正好在所选的HTTP处理程序开始工作前发出该事件

PreSendRequestContent

正好在ASP.NET运行库把响应文本发送给客户之前发出该事件

PreSendRequestHeaders

正好在ASP.NET运行库把HTTP头发送给客户之前发出该事件

ReleaseRequestState,

PostReleaseRequestState

当处理程序释放与当前请求关联的状态信息时发生。ASP.NET 1.x不支持PostReleaseRequestState事件

ResolveRequestCache,

PostResolveRequestCache

当ASP.NET运行库通过输出缓存解决该请求时发生。ASP.NET 1.x不支持PostResolveRequestCache事件

UpdateRequestCache,

PostUpdateRequestCache

当ASP.NET运行库将当前请求的响应存储在输出缓存(用来服务随后的请求)中时发生。ASP.NET 1.x不支持PostUpdateRequestCache事件

所有这些事件由HttpApplication对象提供的,而HTTP模块作为Init方法的一个参数接受该对象。
下面来实现这个接口:

public class MarkerModule : IHttpModule
{

    
public void Init(HttpApplication app)
    {
      
// Register for pipeline events
    }

    
public void Dispose()
    {
      
// Nothing to do here
    }

}


HttpApplication类调用Init方法来装载该模块。在Init方法中,通常只需注册自己的事件处理程序。Dispose方法多半是空的。HTTP模块的核心实际上就是自定义的事件处理程序。

1. 绑定事件

Marker示例模块注册两个管道事件,它们是BeginRequest和EndRequest。BeginRequest是开始处理请求时第一个命中HTTP应用程序对象的事件;EndRequest是表明即将处理完请求,这是实施干预的最后机会的事件。通过处理这两个事件,可以在常规的HTTP处理程序(派生于Page的类)之前和之后,将自定义的文本写入输出流中。

如下清单展示了示例模块的Init和Dispose方法的过程实现:

 

public void Init(HttpApplication app)
{
    
// Register for pipeline events
    app.BeginRequest += new EventHandler(OnBeginRequest);
    app.EndRequest 
+= new EventHandler(OnEndRequest);

}
public void Dispose()
{

}

BeginRequest和EndRequest事件处理程序结构类似。它们从发送方获得对当前HttpApplication对象的引用,并从该引用那里获得HTTP上下文。接着,它们使用Reponse对象追加文本或自定义标题。

 

public void OnBeginRequest(object sender, EventArgs e)
{

    HttpApplication app 
= (HttpApplication) sender;
    HttpContext ctx 
= app.Context;
    
// More code here
    
// PageHeaderText is a constant string defined elsewhere
    ctx.Response.AppendHeader("Author""DinoE");
    ctx.Response.Write(PageHeaderText);

}

public void OnEndRequest(object sender, EventArgs e)
{

    
// Get access to the HTTP context
    HttpApplication app = (HttpApplication) sender;
    HttpContext ctx 
= app.Context;
    
// More code here
    
// Append some custom text
    
// PageFooterText is a constant string defined elsewhere
    ctx.Response.Write(PageFooterText);

}

 

OnBeginRequest写入标准的页面标题文本并添加一个自定义的HTTP头。OnEndRequest只是追加页面的页脚。该HTTP模块的效果如图2.7所示。

图2.7  Marker HTTP模块将一个标题和页脚添加到应用程序内的每个页面

 注意    图中的工具,即IEWatch 2.0,是Microsoft Internet Explorer的一个插件程序,该工具可以分析HTTP/HTTPS请求和HTML源代码。我们可以从http://www.iewatch.com获取它。

Internet Explorer底部的可停靠窗口,展示了浏览器正在发送和接收的所有HTTP头。显然,响应文本中的自定义的标题是可见的。

2. 用配置文件注册该模块

通过向配置文件的<httpModules>节添加一个配置项,可以注册一个新的HTTP模块。<httpModules>配置节的语法类似于HTTP处理程序的语法。使用<add>节点,并规定name和type属性可以添加一个新的模块。name属性包含该模块的公开名称。该名称将被用来选择HttpApplication的Modules集合中的模块。如果该模块激发自定义事件,则该名称还可以在global.asax文件中用作构建自动的事件处理程序的前缀。

<system.web>

<httpModules>

<add name="Marker"

type="ProAspNet20.CS.Components.MarkerModule,ProAspCompLib" />

</httpModules>

</system.web>

type属性使用常见的逗号隔离字符串,它可设置类及其相关程序集的名称。这些配置设置既可以存储在应用程序配置文件中,也可以存储在机器配置文件中。在前一种情况中,只有应用程序的页面受影响;而在后一种情况下,所有应用程序中的所有页面都将由指定的模块进行处理。

这些模块的应用顺序取决于其在配置列表中的物理顺序。可以删掉一个系统模块,并用我们自己的具有类似功能的模块替换它。在这种情况下,在应用程序的web.config文件中,使用<remove>节点删去默认模块,然后使用<add>插入自己的模块。如果需要完全重新定义HTTP模块的应用顺序,可以使用<clear>节点清除所有的默认模块,然后按自己喜欢的顺序重新注册它们。

3. 访问其他HTTP模块

刚刚讨论的示例说明了如何绑定管道事件——即,HttpApplication对象激发的事件。但是其他模块激发的事件是什么呢?HttpApplication对象提供了一个名为Modules的属性,它获得当前应用程序模块的集合。

Modules属性的类型为HttpModuleCollection,其中包括应用程序模块的名称。该集合类继承自NameObjectCollectionBase抽象类,这是一个由字符串和对象组成的组合对的集合。字符串指示模块的公开名称,对象是该模块的真实实例。要访问处理会话状态的模块,需要如下编码:

SessionStateModule sess = app.Modules["Session"];

sess.Start += new EventHandler(OnSessionStart);

如前所述,还可以在global.asax文件中处理HTTP模块引起的事件,并使用ModuleName_EventName规则来命名事件处理程序。模块名称只是在注册一个HTTP模块时需要定义的设置之一。


原文地址:https://www.cnblogs.com/HeroBeast/p/1050593.html