[转]ASP.NET应用程序生命周期趣谈(三) HttpModule
在之前的文章中,我们提到过P_Module(HttpModule)这个能干的程序员哥们儿,它通过在项目经理HttpApplication那里得到的授权,插手整个应用程序级别的事件处理。所有的HttpModule都要实现IHttpModule接口,那么我们看IHttpModule的定义:
namespace System.Web
{
public interface IHttpModule
{
void Dispose();
void Init(HttpApplication context);
}
}
可以看到,HttpModule主要就做了两件事,一个就是大家都明白的释放资源Dispose(),另一个则是初始化。用什么初始化呢?当然是HttpApplication。刚才已经说过,P_Module程序员是经过了项目经理HttpApplication的授权了的,这里我们就可以看到,初始化方法参数就是HttpApplication对象,那么HttpModule又是怎么处理应用程序级别的事件的呢?且看:
我们可以看到,项目经理HttpApplication可是实实在在的放权啊,它非常的相信P_Module可以做好这些事情,所以在初始化方法Init(HttpApplication context)中,程序员P_Module可以注册很多事件,比如说常用的BeginRequest, EndRequest, AuthenticateRequest, AuthorizeRequest等等,还有一些其它的不常用的事件我们就不再赘述。总而言之,HttpModule强大到可以插手整个应用程序周期的所有事件---因为得到了充分授权嘛。下面是注册BeginRequest事件示例代码:
public void Init(HttpApplication context)
{
context.EndRequest+= new EventHandler(context_EndRequest);
}
private void context_EndRequest(object sender, EventArgs e)
{
//do something when the request end
}
那么这里,我们要澄清一个问题:在ASP.NET应用程序生命周期趣谈(一)中我们曾经在后面提到“P_Handler自信的笑了一声,把箱子交还给了项目经理(HttpApplication对象)”,这是不完全准确的。事实上P_Module已经是一个非常高级的程序员,他在有必要的情况下(注册了EndRequest事件)是要review初级程序员P_Handler的工作的,这个review的事件就是HttpApplication的EndRequest的事件。当然,有时候也不review就直接交给HttpApplication了,所以我们得出结论:ASP.NET请求处理是基于管道模型的,request从管道这头进去,经过了HttpModule的一些列处理,到那头儿的HttpHandler再处理,最后再经过管道原路返回。一次请求HttpHandler只能有一个,而HttpModule却可以有若干个。(ps: --!真是废话,MSND上写的比谁都清楚)
总的来说,P_Module高级程序员主要就是从项目经理HttpApplication那得到授权(传入HttpApplication参数)处理应用程序级别的一些重要事件,这些事件贯穿整个应用程序生命周期。我们经常会使用到ASP.NET自带的HttpModule,也有时会使用自定义的HttpModule。ASP.NET自带的HttpModul在以下目录中可以找到:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG/web.config
而我们自己编写的自定义HttpModule则写在我们的应用程序的web.config文件中,也是<HttpModules></HttpModule>节点下,与系统自动配置的并无不同:
可以看到,<HttpModules>节点是在system.web下面的,HibernateUtil就是我曾经写过的一个HttpModule,非常典型,大家可以参考。对与系统自带的HttpModule有很多,这里我就随便挑了一个SessionStateModule来给大家做一个大致的分析,以便大家了解HttpModule如何工作。
简单说一下什么事SessionState。SessionState就是asp.net处理Session的一种机制,简单来说就是它通过管理Session的存储位置,来优化Session的性能和安全性,避免浏览器禁用cookie时session丢失。ASP.NET允许Session存储在三个位置:aspnet_wp.exe(它崩溃session就丢失);aspnet_state.exe(单独的stateserver);sqlserver(存到数据库中)。关于SessionState的内容,请参阅其它相关文章,以后有机会我自己也会写写。
书归正传,那么我们通过反编译SessionStateModule,我们得到两行有用的代码:
public void Init(HttpApplication app)
{
SessionStateSection sessionState = RuntimeConfig.GetAppConfig().SessionState;
//从config文件中读取SessionState配置
this.InitModuleFromConfig(app, sessionState);
//初始化SessionStateModule需要处理的事件
//Other Code
}
第一行从config文件中读取了SessionState的配置(节点<configuration><system.web><sessionState>下面的内容,配置了怎么存储Session等信息),第二行则初始化了SessionStateModule需要处理的事件,我们再看看InitModuleFromModule干了什么:
private void InitModuleFromConfig(HttpApplication app, SessionStateSection config)
{
if (config.Mode != SessionStateMode.Off)
{
app.AddOnAcquireRequestStateAsync(new BeginEventHandler(this.BeginAcquireState), newEndEventHandler(this.EndAcquireState));
app.ReleaseRequestState += new EventHandler(this.OnReleaseState);
app.EndRequest += new EventHandler(this.OnEndRequest);
}
}
我们可以看到,第一行代码中,HttpApplication添加了OnAcquireRequestState的若干事件的处理方法,第二行添加了当SessionState释放时的处理方法,第三行则添加了request接触时的处理方法。SessionStateModule内部如何处理我们这里不做详述,但是我们可以清晰的看到,SessionStateModule处理了应用程序级别的时间,包括SessionState的获得,释放和Request的结束。我们没有发现它处理开始Request的事件,但我们确信它是有能力去做的,只是此种情形下并不需要那么做。下面按照执行顺序列出HttpApplication的事件列表以供参考:
1. BeginRequest //开始
2. AuthenticateRequest //验证
3. AuthorizeRequest //授权
4. AcquireRequestState //获取request state
5. ReleaseRequestState //释放request state
6. UpdateRequestCache //更新cache
7. LogRequest. //这个事件只支持.net 3.0以上版本和IIS7的集成模式
8. EndRequest //结束
所有的HttpModule(包括自定义的和系统自带的)均有能力处理这些事件从而对应用程序产生影响,看来这个P_Module程序员果然很牛啊,项目经理信任它并授权也是有道理的。
然后P_Module作为一个高级程序员,它自身知识积累固然很强大,它的学习能力也是不可忽视的。它可以自己学习(创建)一些新的能力(自定义Module),经典的例子就是它网上盛传的它能在每个页面中都加入一些文字;这里我只简单的说明我用过的一个P_Module自建的在EndRequest事件中关闭NHibernateSession的例子:
首先,我们创建一个类HibernateUtil,继承接口IHttpModule,并实现接口方法:
public class HibernateUtil : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
}
}
然后,注册EndRequest事件:
public void Init(HttpApplication context)
{
context.EndRequest+= new EventHandler(context_EndRequest);
}
private void context_EndRequest(object sender, EventArgs e)
{
CloseSession();
}
最后,配置Web.config:
此时,我们就完成了一个自定义的HttpModule。这个小例子并不难,主要是说明了HttpModule的创建流程和方法,而本篇文章也难度也不是很高,希望对大家能有所帮助,欢迎拍砖,少扔鸡蛋,挺贵的,谢谢! ^_^
[转]ASP.NET应用程序生命周期趣谈(三) HttpModule的更多相关文章
- [转]ASP.NET应用程序生命周期趣谈(五) IIS7瞎说
Ps:建议初学者在阅读本文之前,先简要了解一下之前的几篇文章,以便于熟悉本文提到的一些关于IIS6的内容,方便理解.仅供参考. PS:为什么叫瞎说呢?我觉得自己理解的并不到位,只能是作为一个传声筒,希 ...
- [转]ASP.NET应用程序生命周期趣谈(一)
这几天一直在看ASP.NET应用程序生命周期,真是太难了,我理解起来费了劲了,但偏偏它又是那么重要,所以我希望能给大家带来一篇容易理解又好用的文章来帮助学习ASP.NET应用程序生命周期.这篇就是了. ...
- [转]ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期
在之前的三篇文章中,我们还算简明扼要的学习了asp.net的整个生命周期,我们知道了一个Request进来以后先去ISAPI Filter,发现是asp.net程序后又ASPNET_ISAPI.dll ...
- [转]ASP.NET应用程序生命周期趣谈(二)
在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1, IIS肯定是没有眼睛 ...
- ASP.NET 应用程序生命周期
1.请求到达IIS服务器,IIS根据文件后缀找到对应的ISAPI(Internet Server API)扩展来处理,这个配置可在网站属性里的“根目录”选项卡中的“配置”里看到.可以看到,ashx.a ...
- asp.net应用程序生命周期和asp.net网页的生命周期
一.asp.net应用程序生命周期 asp.net应用程序生命周期以浏览器向web服务器(比如IIS服务器)发送请求为起点,先后经历web服务器下的ISAPI(Internet Server Appl ...
- asp.net应用程序生命周期
asp.net应用程序生命周期(流程文字描述版) 请求——>IIS——>ISAPI映射——>交给asp.net(即为IIS的扩展)——>通知Application类创建一个应用 ...
- ASP.NET 应用程序生命周期概述[转自MSDN]
本文转自:http://msdn.microsoft.com/zh-cn/library/ms178473(VS.80).aspx 下表描述了 ASP.NET 应用程序生命周期的各个阶段. 阶段 ...
- IIS 7.0 的 ASP.NET 应用程序生命周期概述(转载)
IIS 7.0 的 ASP.NET 应用程序生命周期概述更新:2007 年 11 月本主题介绍在 IIS 7.0 集成模式下运行以及与 IIS 7.0 或更高版本一起运行的 ASP.NET 应用程序的 ...
随机推荐
- Ubuntu(Linux) + mono + jexus +asp.net MVC3 部署
感谢 张善友 的建议,我把 微信订餐 由nginx 改成 jexus,目前运行状况来说,确实稳定了很多,再次感谢. 部署步骤参考 jexus官网:http://www.jexus.org/ htt ...
- Linux 桌面系统字体配置要略
字体显示效果测试 这一段是为了测试宋体字的显示效果,包括宋体里面自带的英文字体,“This is english,how does it look like?”.这一行是小字.后面几个字是加粗的宋体. ...
- 借助Nodejs探究WebSocket
文章导读: 一.概述-what's WebSocket? 二.运行在浏览器中的WebSocket客户端+使用ws模块搭建的简单服务器 三.Node中的WebSocket 四.socket.io 五.扩 ...
- 数据预处理中归一化(Normalization)与损失函数中正则化(Regularization)解惑
背景:数据挖掘/机器学习中的术语较多,而且我的知识有限.之前一直疑惑正则这个概念.所以写了篇博文梳理下 摘要: 1.正则化(Regularization) 1.1 正则化的目的 1.2 正则化的L1范 ...
- HTML5_04之SVG绘图
1.关于Canvas绘制图像: 问题:需要绘制多张图片时,必须等待所有图片加载完成才能开始绘制:而每张图片都是异步请求,彼此没有先后顺序,哪一张先加载完成完全无法预测: 方案: var progres ...
- 【java】细说 JAVA中 标注 注解(annotation)
Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用 下面我们来详细说说这个注解,到底是怎么一 ...
- MVC5 网站开发之八 栏目功能 添加、修改和删除
本次实现栏目的浏览.添加.修改和删除. 栏目一共有三种类型. 常规栏目-可以添加子栏目,也可以添加内容模型.当不选择内容模型时,不能添加内容. 单页栏目-栏目只有一个页面,可以设置视图. 链接栏目-栏 ...
- Android中如何使用命令行查看内嵌数据库SQLite3
转载博客:http://www.linuxidc.com/Linux/2011-06/37135.htm 在上图中,除了最后一个红色的方框,其它方框都是adb shell下的命令. [1]在Andro ...
- .NET Core采用的全新配置系统[6]: 深入了解三种针对文件(JSON、XML与INI)的配置源
物理文件是我们最常用到的原始配置的载体,最佳的配置文件格式主要由三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...
- J2EE 项目读写分离
先回答下 1.为啥要读写分离? 大家都知道最初开始,一个项目对应一个数据库,基本是一对一的,但是由于后来用户及数据还有访问的急剧增多, 系统在数据的读写上出现了瓶颈,为了让提高效率,想读和写不相互影响 ...