在之前的文章中,我们提到过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的更多相关文章

  1. [转]ASP.NET应用程序生命周期趣谈(五) IIS7瞎说

    Ps:建议初学者在阅读本文之前,先简要了解一下之前的几篇文章,以便于熟悉本文提到的一些关于IIS6的内容,方便理解.仅供参考. PS:为什么叫瞎说呢?我觉得自己理解的并不到位,只能是作为一个传声筒,希 ...

  2. [转]ASP.NET应用程序生命周期趣谈(一)

    这几天一直在看ASP.NET应用程序生命周期,真是太难了,我理解起来费了劲了,但偏偏它又是那么重要,所以我希望能给大家带来一篇容易理解又好用的文章来帮助学习ASP.NET应用程序生命周期.这篇就是了. ...

  3. [转]ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期

    在之前的三篇文章中,我们还算简明扼要的学习了asp.net的整个生命周期,我们知道了一个Request进来以后先去ISAPI Filter,发现是asp.net程序后又ASPNET_ISAPI.dll ...

  4. [转]ASP.NET应用程序生命周期趣谈(二)

    在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1,    IIS肯定是没有眼睛 ...

  5. ASP.NET 应用程序生命周期

    1.请求到达IIS服务器,IIS根据文件后缀找到对应的ISAPI(Internet Server API)扩展来处理,这个配置可在网站属性里的“根目录”选项卡中的“配置”里看到.可以看到,ashx.a ...

  6. asp.net应用程序生命周期和asp.net网页的生命周期

    一.asp.net应用程序生命周期 asp.net应用程序生命周期以浏览器向web服务器(比如IIS服务器)发送请求为起点,先后经历web服务器下的ISAPI(Internet Server Appl ...

  7. asp.net应用程序生命周期

    asp.net应用程序生命周期(流程文字描述版) 请求——>IIS——>ISAPI映射——>交给asp.net(即为IIS的扩展)——>通知Application类创建一个应用 ...

  8. ASP.NET 应用程序生命周期概述[转自MSDN]

    本文转自:http://msdn.microsoft.com/zh-cn/library/ms178473(VS.80).aspx 下表描述了 ASP.NET 应用程序生命周期的各个阶段.   阶段 ...

  9. IIS 7.0 的 ASP.NET 应用程序生命周期概述(转载)

    IIS 7.0 的 ASP.NET 应用程序生命周期概述更新:2007 年 11 月本主题介绍在 IIS 7.0 集成模式下运行以及与 IIS 7.0 或更高版本一起运行的 ASP.NET 应用程序的 ...

随机推荐

  1. Ubuntu(Linux) + mono + jexus +asp.net MVC3 部署

    感谢  张善友 的建议,我把 微信订餐  由nginx 改成 jexus,目前运行状况来说,确实稳定了很多,再次感谢. 部署步骤参考 jexus官网:http://www.jexus.org/ htt ...

  2. Linux 桌面系统字体配置要略

    字体显示效果测试 这一段是为了测试宋体字的显示效果,包括宋体里面自带的英文字体,“This is english,how does it look like?”.这一行是小字.后面几个字是加粗的宋体. ...

  3. 借助Nodejs探究WebSocket

    文章导读: 一.概述-what's WebSocket? 二.运行在浏览器中的WebSocket客户端+使用ws模块搭建的简单服务器 三.Node中的WebSocket 四.socket.io 五.扩 ...

  4. 数据预处理中归一化(Normalization)与损失函数中正则化(Regularization)解惑

    背景:数据挖掘/机器学习中的术语较多,而且我的知识有限.之前一直疑惑正则这个概念.所以写了篇博文梳理下 摘要: 1.正则化(Regularization) 1.1 正则化的目的 1.2 正则化的L1范 ...

  5. HTML5_04之SVG绘图

    1.关于Canvas绘制图像: 问题:需要绘制多张图片时,必须等待所有图片加载完成才能开始绘制:而每张图片都是异步请求,彼此没有先后顺序,哪一张先加载完成完全无法预测: 方案: var progres ...

  6. 【java】细说 JAVA中 标注 注解(annotation)

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用 下面我们来详细说说这个注解,到底是怎么一 ...

  7. MVC5 网站开发之八 栏目功能 添加、修改和删除

    本次实现栏目的浏览.添加.修改和删除. 栏目一共有三种类型. 常规栏目-可以添加子栏目,也可以添加内容模型.当不选择内容模型时,不能添加内容. 单页栏目-栏目只有一个页面,可以设置视图. 链接栏目-栏 ...

  8. Android中如何使用命令行查看内嵌数据库SQLite3

    转载博客:http://www.linuxidc.com/Linux/2011-06/37135.htm 在上图中,除了最后一个红色的方框,其它方框都是adb shell下的命令. [1]在Andro ...

  9. .NET Core采用的全新配置系统[6]: 深入了解三种针对文件(JSON、XML与INI)的配置源

    物理文件是我们最常用到的原始配置的载体,最佳的配置文件格式主要由三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...

  10. J2EE 项目读写分离

    先回答下 1.为啥要读写分离? 大家都知道最初开始,一个项目对应一个数据库,基本是一对一的,但是由于后来用户及数据还有访问的急剧增多, 系统在数据的读写上出现了瓶颈,为了让提高效率,想读和写不相互影响 ...