自定义HttpModule的一些经验


自定义web模块,需继承System.Web.IHttpModule接口

拦截对该服务器所有的http请求

第一步:将自定义module类使用强名编译,并放在GAC中。

Windows7不能直接把dll文件拖到GAC中,只能只用GACUtil工具。

方法是:打开Visual Studio命令行,提示进入目录:C:\Program Files\Microsoft Visual Studio 10.0\VC,

gacutil /i [assemblypath],将该Assembly安装在GAC中

gacutil /l [assemblyName], 出现Assembly的详细信息

gacutil /u [assemblyName], 卸载该Assembly

第二步:把模块加在machine.config, web.config或者IIS的applicationhost.config里。

IIS的applicationhost.config位于(%windir%\system32\inetsrv\config\applicationhost.config)

<location path="" overrideMode="Allow">
        <system.webServer>
            <modules>
            <add name="HttpRequestModule" type="RequestModuleNS.RequestModuleClass,RequestModuleAssembly,Version=1.0.0.0,Culture=neutral,PublicKeyToken=5510eb446e44a3fd"/>
         ...................... 

其中,type的格式为:“NameSpaceName.ClassName,AssemblyName, StrongName”

只拦截对某web程序的Request

将自定义模块单独编译为一个dll文件,并通过dll引用添加到web程序

修改该程序内部的web.config文件

<configuration>    
    <system.webServer> <!-- IIS7.0集成模式下 -->
        <validation validateIntegratedModeConfiguration="false"/>
        <modules>
            <add name="HttpRequestModule" type="RequestModuleNS.RequestModuleClass,RequestModuleAssembly"/>
        </modules>
    </system.webServer>
    <system.web> <!-- IIS7.0经典模式或者IIS之前版本 -->
        <compilation debug="true" targetFramework="4.0" />
        <httpModules>
          <add name="HttpRequestModule" type="RequestModuleNS.RequestModuleClass,RequestModuleAssembly"/>
        </httpModules>
    </system.web>    
</configuration>

把自定义模块的类文件放在web网站的app_code目录下,并修改该程序内部的web.config文件

<configuration>
    <system.webServer>
        <validation validateIntegratedModeConfiguration="false"/>
        <modules>
            <add name="HttpRequestModule" type="RequestModuleNS.RequestModuleClass"/>
        </modules>
    </system.webServer>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <httpModules>
          <add name="HttpRequestModule" type="RequestModuleNS.RequestModuleClass"/>
        </httpModules>
    </system.web>
</configuration>

其中,type格式为“NameSpaceName.ClassName“。

奇怪的是,在第二种方式下,在VS debug模式下访问.wmv文件时不能触发module,访问.aspx文件时则可以。而第一种方式下,访问程序里的.wmv文件和.aspx文件都可以触发该自定义module。笔者不知为何,索性改回第一种方式。留待以后再探索。(探索结果:原来不是第二种方式的问题,而是在测试时网站端口改变,而旧的debug线程未被杀死,所有用旧的url直接访问了过期的旧线程。这是不是VS的一个bug,当退出debug时,启动的临时线程并未被杀死,而重新启动debug时,旧的临时server线程也未被新的替代,好大一个bug哇。

代码详解

需要继承System.Web.IHttpModule接口。该接口只有两个方法:System.Web.IHttpModule.Dispose()和System.Web.IHttpModule.Init(System.Web.HttpApplication)

    public class RequestModuleClass: IHttpModule
    { 
        public void Dispose()
        {
            //clean-up code here.
        }

        public void Init(HttpApplication app)
        {            
            app.BeginRequest += new EventHandler(app_BeginRequest);
            app.EndRequest += new EventHandler(app_EndRequest);
        }

        void app_EndRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            if (app.Request.Cookies.Get("Cookie1") == null)
            {
                return;
            }
       ..............
        }

        void app_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            string videoId = app.Request.QueryString["elementId"];
            string requestUrl = app.Request.Url.ToString();
            app.Request.Cookies.Add(new HttpCookie("Cookie1", "Just A Test"));
        try
            {
          //Test to see if the duplicate cookie can be added. The result shows no error pops up.
                app.Request.Cookies.Add(new HttpCookie("Cookie1", "Just A Test to Override"));
       }
            catch (Exception ex)
            {
            }
        }        
        #endregion
    }
  • HttpApplication对象是Asp.net内部生成并分给应用程序的。但是因为HttpApplication一次只能处理一个请求,所以避免了并发的很多麻烦。

  • 每个HttpModule对每个request都是单例的,也就是说,在HttpModule里定义的全局变量是所以request共享的,所以不要把每个request自己的参数定义在HttpModule里。在我的代码里,把要保存的变量放在了HttpApplication.Request.Cookies里,可是只能存string类型。

  • HttpApplication.Request.Cookies重复添加相同名字的HttpCookie对象,直接覆盖,不会报错。

知识共享许可协议
《自定义HttpModule的一些经验》 常伟华 创作。
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议 | 3.0 中国大陆许可协议进行许可。

站内公告