HttpModules

玩.Net 的人都知道,服务器对一个web请求的处理过程封装在一个叫做处理管道的“黑匣子”里面,这个“黑匣子”里面有很多针对一次请求处理的事件,其中微软只暴露出19个给我们程序猿使用(小弟下篇博文会对这个“黑匣子”进行个简单的整理)。19个事件中我们其实是可以通过事件注册来让它做我们想做的事,本文就简单来啰嗦下这个话题。

一个动态的url请求到达IIS服务器之后,首先接待它的是HttpRuntime,该类很庞大,负责对一次完整请求的所有处理。因为一次处理过程其实是相当艰辛的,它一个人忙不过来,于是找HttpContext和HttpApplication两个伙计来帮忙而且两人各有分工,HttpContext主要封装了原始的请求报文,还有几个得力助手,比较出名的是Response、Request、Server几人,分别负责向浏览器输出、获取浏览器请求参数、服务器端的一些助手类工作。而那个处理管道也就是19个事件在哪里呢?就是在HttpApplication这个类中,HttpApplication和HttpContext两个类也是密不可分的,就好像HttpContext是原料厂,HttpApplication是对原始材料进行处理加工的生产厂(这些都是对HttpModule进行处理的基本储备知识)

本着低耦合高内聚的经典设计思想,我先在项目中见一个类库项目MyHttpModule,里面建类RegModule。由上面知识点的罗列可以想到,如果要在RegModule类中对处理管道中的事件进行注册的话,这个类必须包含HttpApplication、HttpContext这些东东才行,因为那些事件是在HttpApplication里的嘛,所以它必须实现一个叫做IHttpModule的接口,该接口在命名空间system.web下,接口定义如下:

namespace System.Web
{
    // 摘要:
    //     向实现类提供模块初始化和处置事件。
    public interface IHttpModule
    {
        // 摘要:
        //     处置由实现 System.Web.IHttpModule 的模块使用的资源(内存除外)。
        void Dispose();
        //
        // 摘要:
        //     初始化模块,并使其为处理请求做好准备。
        //
        // 参数:
        //   context:
        //     一个 System.Web.HttpApplication,它提供对 ASP.NET 应用程序内所有应用程序对象的公用的方法、属性和事件的访问
        void Init(HttpApplication context);
    }
}

熟悉的HttpApplication作为该接口的Init方法参数出现,是不是让你有点兴奋?

在RegModule中实现IHttpModule中的方法,代码如下:

class RegModule:IHttpModule
    {
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            throw new NotImplementedException();
        }
    }

在Init方法里,作为HttpApplication类型的context参数,便具有了处理管道中的那些个事件。既然是事件就可以通过delegate来注册吧(关于delegate的使用细节不再赘述),先来个简单的,对BegainRequest这个处理一开始第一个执行的事件进行注册,主要代码如下:

  public void Init(HttpApplication context)
        {
            //throw new NotImplementedException();
            context.BeginRequest+=new EventHandler(context_BeginRequest);
        }

        public void context_BeginRequest(object sender, EventArgs e)
        {
           
        }

到这里,其实你应该看出来了,参数sender就代表HttpContext,使用as关键字将它打回原形,就可以调用context里的Write、SetCookie等等那些个方法了,我就简单的输出一句话有个意思就行,代码:(sender as HttpContext).Response.Write("Hello,你知道我是从哪里来的吗?");

至此,在这个类中对Module的注册就算是完成了,那么怎么在你的web程序中使用呢?有两点,首先肯定要引用当前类库;其次在config文件中添加<Httpmodule>配置节。添加配置代码如下:

    <system.web>
        <compilation debug="false" targetFramework="4.0" />
      <httpModules>
        <add name="myHttpModule" type="MyHttpModule.RegModule,MyHttpModule"/>
      </httpModules>
    </system.web>

name随便起,type中有两部分用逗号隔开,前面是注册Module的命名空间.类名,后面其实是引用的程序集名,我当前默认程序集名与类名相同了。完成这些之后添加个aspx页面测试一把,直接空页面进行浏览

是不是很爽呢……哈哈

原文地址:https://www.cnblogs.com/luseike/p/2732190.html