• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ASP.NET3.5核心编程学习笔记(46):HTTP模块的编写

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  对于每个运行中的应用程序,ASP.NET都维护着一个HttpApplication对象的池,特定的请求会逐一由池中的实例处理。这些对象基于定义在global.asax的类创建,如果未定义global.asax,则基于HttpApplication类创建。负责处理请求的HttpApplication对象的最终目标是获取HTTP处理程序。

  在获取目标HTTP处理程序前,HttpApplication对象要使请求流经HTTP模块的管道。HTTP模块是实现IHttpModule接口的.NET Framework类,用于筛选请求的中原始数据。HTTP模块会基于每个应用程序的web.config文件进行配置,但所有ASP.NET应用程序都会继承全局的web.config文件中配置的许多系统HTTP模块。

  一般来讲,HTTP模块可以对请求进行预处理和后处理,它会监听和处理系统事件和其他模块引发的事件。ASP.NET固有的可配置特性使我们能够编写和注册自定义的HTTP模块,并将其插入到ASP.NET运行时管道中来处理系统和自定义事件。

IHttpModule接口

  IHttpModule接口定义了两个方法:Init和Dispose。Init方法用于对模块进行初始化,为处理请求做好准备。同时,我们还可以通过它来订阅所需的事件,以便得到通知。Dispose方法用于释放当前模块占用的资源(除内存外的所有资源)。我们一般在Dispose方法中关闭数据库连接或文件句柄。这两个方法的签名如下:

void Init(HttpApplication app);
void Dispose();

  下表列出了HTTP模块能够监听和处理的事件:

自定义的HTTP模块

  让我们编写一个相对简单的自定义模块Marker,它对当前应用程序处理的所有页面添加页眉和页脚。该类的代码如下:

using System;
using System.Web;
using System.IO;



namespace Core35.Components
{
public class MarkerModule : IHttpModule
{
#region Constants
const string PageHeaderText = "<table width=100% style='font-family:verdana;font-size:8pt;' bgcolor=cyan><tr><td align=center>You must register to continue enjoy this Web site! Click <b><a href=http://www.contoso.com>here</a>.</b></td></tr></table>";
const string PageFooterText = "<table width=100% style='font-family:verdana;font-size:8pt;' bgcolor=cyan><tr><td align=center>Courtesy of <b>Programming Microsoft ASP.NET 3.5</b></td></tr></table>";
#endregion


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

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


#region Helpers
public void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication app
= (HttpApplication) sender;
HttpContext ctx
= app.Context;

// More code here
if (!ShouldHook(ctx))
return;

// Add custom header to the HTTP response
ctx.Response.AppendHeader("Author", "DinoE");
ctx.Response.Write(PageHeaderText);
}

public void OnEndRequest(object sender, EventArgs e)
{
HttpApplication app
= (HttpApplication)sender;
HttpContext ctx
= app.Context;

// More code here
if (!ShouldHook(ctx))
return;

// Append some custom text
ctx.Response.Write(PageFooterText);
}

public bool ShouldHook(HttpContext ctx)
{
return ctx.Request.Path.EndsWith("testmarker.aspx", StringComparison.OrdinalIgnoreCase);
}
#endregion
}
}

  OnBeginRequest添加了一个普通的页面眉和一个自定义的HTTP标头。OnEndRequest只添加页脚。

使用配置文件来注册该模块

  我们需要在web.config注册HTTP模块,以使模块生效:

<system.web>
<httpModules>
<add name="Marker" type="Core35.Components.MarkerModule,Core35Lib" />
</httpModules>
</system.web>

  模块生效的顺序取决于它们在配置列表中的物理顺序。我们可以移除某个系统模块,并替换成具有类似功能的自定义模块。在这种情况下,可以在应用程序的web.config文件中使用<remove>节点来删除默认的模块,通过<add>来插入自定义的模块。如果希望为应用程序重新定义所有HTTP模块的顺序,可使用<clear>节点,然后按意愿重新注册。

  HTTP模块只在应用程序启动时加载和初始化一次。与HTTP处理程序不同,模块会作用于所有请求。

其他HTTP模块的访问

  上例演示了如何订阅管道的事件(即由HttpApplication对象引发的事件)。那么,如果想订阅其他模块引发的事件,如何捕获呢?HttpApplication对象提供了一个名为Modubles的属性,用于获取当前应用程序中模块的集合。

  Modules的类型为HttpModuleCollection,包含应用程序中各模块的名称。该集合类继承于抽象类NameObjectCollectionBase,这个抽象类代表由字符串/对象对组成的集合。字符串指示模块的公共名称,对象是模块的实例。如要访问处理会话状态的模块:

SessionStateModule sess = app.Modules["Session"];
sess.Start
+= new EventHandler(OnSessionStart);

  我们还可在global.asac文件中使用ModuleName_EventNamer的事件处理程序命名范式来处理HTTP模块引发的事件。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Asp.net ajax定时刷新页面发布时间:2022-07-10
下一篇:
Writing an XML-RPC server or client in ASP.Net: Part 1发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap