httpModules与Http模块
httpModules是往当前应用程序添加HttpModule(http模块)的标签。配置节如下
<httpModules>
<add name="ModuleName"
type=".NET Class, Assembly [,Version=version number]
[,Culture=culture] [,PublicKeyToken=token]"/>
<remove... />
<clear/>
</httpModules>
提起httpModule不得不提一下Http请求处理流程
ASP.NET对请求处理的过程:
当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI.dll,ASPNET_ISAPI.dll会通过http管道(Http PipeLine)将请求发送给ASPNET_WP.exe进程,在ASPNET_WP.exe进程中通过HttpRuntime来处理这个请求,处理完毕将结果返回客户端。
Http 管道:

1. HttpRuntime将Http请求转交给 HttpApplication,HttpApplication代表着程序员创建的Web应用程序。HttpApplication创建针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其他对象,主要是HttpRequest、HttpResponse、HttpSessionState等。这些对象在程序中可以通过Page类或者Context类进行访问。、
2. 接下来Http请求通过一系列Module,这些Module对Http请求具有完全的控制权。这些Module可以做一些执行某个实际工作前的事情。
3. Http请求经过所有的Module之后,它会被HttpHandler处理。在这一步,执行实际的一些操作,通常也就是.aspx页面所完成的业务逻辑。可能你会觉得在创建.aspx页面并没有体会到这一过程,但是,你一定知道,.aspx 页面继承自Page类,我们看一下Page类的签名:
public class Page : TemplateControl, IHttpHandler{
// 代码省略
}
可以看到,Page类实现了IHttpHandler接口,HttpHandler也是Http请求处理的最底层。
4.HttpHandler处理完以后,Http请求再一次回到Module,此时Module可以做一些某个工作已经完成了之后的事情。
从第二步到第四步可以用下面的图来展示

在http请求的处理过程中,只能调用一个HttpHandler,但可以调用多个HttpModule。
下面则详细说说HttpModule
HTTP 模块是一个在每次针对应用程序发出请求时调用的程序集。HTTP 模块作为请求管道的一部分调用,它们能够在整个请求过程中访问生命周期事件。因此,HTTP 模块使您可以检查传入的请求并根据该请求进行操作。它们还使您可以检查传出的响应并修改它。
ASP.NET HTTP 模块针对所有请求调用,这与 ISAPI 筛选器类似。但是它们是用托管代码编写的,而且可以与 ASP.NET 应用程序的生命周期完全集成。可以将自定义模块源代码放在应用程序的 App_Code 文件夹中,也可以将经过编译的自定义模块作为程序集放在应用程序的 Bin 文件夹中。
ASP.NET 使用模块来实现各个应用程序功能,其中包括 Forms 身份验证、缓存、会话状态和客户端脚本服务。在每种情况下,如果这些服务处于启用状态,模块会作为请求的一部分调用,并执行在任何单一页请求范围之外的任务。模块可以使用应用程序事件,可能会引发可在 Global.asax 文件中处理的事件。
功能:
模块可以订阅多种请求管道通知。模块可以接收 HttpApplication 对象的事件通知。
使用场景
HTTP 模块通常具有以下用途:
- 安全 因为您可以检查传入的请求,所以 HTTP 模块可以在调用请求页、XML Web services 或处理程序之前执行自定义的身份验证或其他安全检查。在以集成模式运行的 Internet 信息服务 (IIS) 7.0 中,可以将 Forms 身份验证扩展到应用程序中的所有内容类型。
- 统计信息和日志记录 因为 HTTP 模块是在每次请求时调用的,所以,您可以将请求统计信息和日志信息收集到一个集中的模块中,而不是收集到各页中。
- 自定义的页眉或页脚 因为您可以修改传出响应,所以可以在每一个页面或 XML Web services 响应中插入内容,如自定义的标头信息。
ASP.NET中一些内置的HttpModule
|
名称 |
类型 |
功能 |
|
OutputCache |
System.Web.Caching.OutputCacheModule |
页面级输出缓存 |
|
Session |
System.Web.SessionState.SessionStateModule |
Session状态管理 |
|
WindowsAuthentication |
System.Web.Security.WindowsAuthenticationModule |
用集成Windows身份验证进行客户端验证 |
|
FormsAuthentication |
System.Web.Security.FormsAuthenticationModule |
用基于Cookie的窗体身份验证进行客户端身份验证 |
|
PassportAuthentication |
System.Web.Security.PassportAuthenticationModule |
用MS护照进行客户身份验证 |
|
RoleManager |
System.Web.Security.RoleManagerModule |
管理当前用户角色 |
|
UrlAuthorization |
System.Web.Security.UrlAuthorizationModule |
判断用户是否被授权访问某一URL |
|
FileAuthorization |
System.Web.Security.FileAuthorizationModule |
判断用户是否被授权访问某一资源 |
|
AnonymousIdentification |
System.Web.Security.AnonymousIdentificationModule |
管理Asp.Net应用程序中的匿名访问 |
|
Profile |
System.Web.Profile.ProfileModule |
管理用户档案文件的创立及相关事件 |
|
ErrorHandlerModule |
System.Web.Mobile.ErrorHandlerModule |
捕捉异常,格式化错误提示字符,传递给客户端程序 |
下面摘抄了MSDN上的一个例子,自定义一个HttpModule
HttpModule必须实现接口System.Web.IHttpModule
namespace FastDoge.Study
{
public class MyModule : IHttpModule
{
public void Dispose()
{ } public void Init(HttpApplication context)
{
context.BeginRequest +=
(new EventHandler(this.Application_BeginRequest));
context.EndRequest +=
(new EventHandler(this.Application_EndRequest));
} private void Application_BeginRequest(Object source,
EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<h1><font color=red>" +
"HelloWorldModule: Beginning of Request" +
"</font></h1><hr>");
} private void Application_EndRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<hr><h1><font color=red>" +
"HelloWorldModule: End of Request</font></h1>");
} }
在 IIS 6.0 和 IIS 7.0 经典模式下运行的Web.config添加以下配置
<configuration>
<system.web>
<httpModules>
<add name="myModule" type="FastDoge.Study.MyModule"/>
</httpModules>
</system.web>
</configuration>
由于鄙人用的是IIS7集成模式,配置会不一样
<system.webServer>
<modules>
<add name="myModule" type="FastDoge.Study.MyModule"/>
</modules>
</system.webServer>
效果如下所示

当然网站不能是空网站,否则输出的只是一行
<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>
的字符串。在Init方法中传入的HttpApplication 对象可以绑定的事件可以参考ASP.NET 应用程序生命周期中提到的,事件一共20几个。
在网上找了一幅图,列出了事件触发的顺序

BeginRequest和PreRequestHandlerExecute之间的事件是在服务器执行HttpHandler处理之前触发。
PostRequestHandlerExecute和PreSendRequestContent之间的事件是在服务器执行Handler处理之后触发。
可是鄙人纠结的一点在于没发现某个ASP.NET内置的HttpModule调用了Handler。对于ASP.NET WebForm来说,每个Page都是一个Handler。而对ASP.NET MVC来说,在之前看蒋金楠老是的著作时看到的是触发一个UrlRoutingModule,它在OnPostResolveRequestCache事件中给HttpContext指定了一个MvcHandler。这样就会使得HttpHandler会被调用?或许需要看一下源码了。另外还有一个值得学习的地方就是这种模块的添加以及往Application注册事件的形式,使得HttpApplication具备的较好的灵活性。
在入行之初写过一篇博客,就用到HttpModule,当时有位园友评论说可以用Global.asax。结合当时的场景确实如此。但是两者对比起来肯定有弊有利。
模块相对于 Global.asax 文件具有如下优点:模块可以进行封装,因此可以在创建一次后在许多不同的应用程序中使用。
用 Global.asax 文件的好处在于可以处理其他已注册事件,如 Session_Start 和 Session_End。此外,Global.asax 文件还允许您实例化可在整个应用程序中使用的全局对象。
当您必须创建依赖应用程序事件的代码,并且符合以下条件时,都应该使用模块:
- 希望在其他应用程序中重用该模块。
- 希望避免将复杂代码放在 Global.asax 文件中。
- 该模块应用于管道中的所有请求(仅限 IIS 7.0 集成模式)。
当您必须创建依赖应用程序事件的代码并且不需要跨应用程序重用代码时,应该将代码添加到 Global.asax 文件中。
httpModules与Http模块的更多相关文章
- 关于asp.net mvc中的httpModules 与 httpHandler
ASP.NET对请求处理的过程: 当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI.dll,A ...
- httpModules 与 httpHandlers
ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI.dll,AS ...
- HttpHander与httpModel配置与应用
ASP.NET对请求处理的过程: 当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll, ...
- HttpModule与HttpHandler详解
ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,A ...
- [转]Session服务器配置指南与使用经验
本文转自:http://www.cnblogs.com/zhangziqiu/archive/2009/03/26/SessionServer.html 一.摘要 所有Web程序都会使用Session ...
- Session服务器配置指南与使用经验
一.摘要 所有Web程序都会使用Session保存数据. 使用独立的Session服务器可以解决负载均衡场景中的Session共享问题.本文介绍.NET平台下建立Session服务器的几种办法, 并介 ...
- ASP.NET 学习的总结
应用程序域 使用.Net建立的可执行程序*.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.Net引入的一个新概念,它比进程所占用的资源要少,可以被看做 ...
- IHttpModule与IHttpHandler的区别整理
IHttpModule与IHttpHandler的区别整理1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行 ...
- <转>ASP.NET学习笔记之理解MVC底层运行机制
ASP.NET MVC架构与实战系列之一:理解MVC底层运行机制 今天,我将开启一个崭新的话题:ASP.NET MVC框架的探讨.首先,我们回顾一下ASP.NET Web Form技术与ASP.NET ...
随机推荐
- Redis 集群的合纵与连横
之前一篇写了关于 Redis 的性能,这篇就写写我认为比性能更重要的扩展性方面的主题. 如果再给我一次回到好几年前的机会,对于使用 Redis 我一开始就要好好考虑将来的扩展问题.就像我们做数据库分库 ...
- Android应用安全开发之浅谈网页打开APP
一.网页打开APP简介 Android有一个特性,可以通过点击网页内的某个链接打开APP,或者在其他APP中通过点击某个链接打开另外一个APP(AppLink),一些用户量比较大的APP,已经通过发布 ...
- EQueue性能测试计划
1.发送消息吞吐量的测试: 1)单台producer单个进程的发送消息tps2)单台producer多个进程的发送消息tps3)单台broker的接收消息tps,由于单台producer可能压不满,所 ...
- 使用NServiceBus开发分布式应用
系列主题:基于消息的软件架构模型演变 NServiceBus 是一个.Net平台下开源的消息服务框架,这类产品有时也被称作ESB(Enterprise Service Bus)--企业服务总线.NSe ...
- [ZigBee] 16、Zigbee协议栈应用(二)——基于OSAL的无线控制LED闪烁分析(下)
说在前面:上一篇介绍了无线LED闪烁实现的OSAL部分,本篇介绍如何实现无线数据收发及数据处理: 上一篇是用SI跟着流程查看源码,我个人认为以架构的思维去了解代码能让人更清晰 ::ZMain.c程序入 ...
- 使用HTML5的History API
HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL.这个功能很有用,例如通过一段JavaScript代码局部加载页面的内容,你希望通过改变当前页面的 ...
- js实用篇之String对象
概述 String对象是JavaScript原生提供的三个包装对象之一,用来生成字符串的包装对象. var s1 = 'abc'; var s2 = new String('abc'); typeof ...
- Java Math 取整的方式
1.Math.floor floor,英文原意:地板. Math.floor 函数是求一个浮点数的地板,就是 向下 求一个最接近它的整数,它的值肯定会小于或等于这个浮点数. 2.Math.ceil c ...
- 开源地图SharpMap源码解析-(1)简介
1.简介 SharpMap最新版基于.NET Framework 4,采用C#开发的地图渲染引擎,非常易于使用.我这次研究的是比较稳定发布的V1.1版本.可以在GitHub下载该源码,地址:https ...
- LINQ系列:Linq to Object集合操作符
集合操作符对元素的集合或序列集合进行操作,并返回一个集合.LINQ共有4种集合查询操作符:Distinct.Union.Intersect和Except. 1. Distinct Distinct操作 ...