• 重写HttpModule机制


      写这篇文章,心里多少有些不安。主要是因为我对在web.config文件中对HttpModule进行多个自定义HttpModule的配置与之前一位牛人的见解有些不同【具体参见http://www.cnblogs.com/Jax/archive/2007/10/02/912884.html】。所以这篇文章仅仅只是我个人浅见,希望对HttpModule机制有深入了解的人能指出我理解有偏差的地方,同时也希望大家积极讨论,共同进步。

      最近因为用SlickUpload,它做上传效果确实很拉风,功能也很强。但由于付费,使用之后一直有个div层显示,并且往它的官网上重定向。所以就萌发了重写HttpModule机制的想法。

      熟悉Asp.Net的朋友都应该知道HttpModule,它是处理客户端请求中很重要的一个环节。所有客户端的请求都必须

    通过它进行一些前期处理后,再由它交给HttpHandler进行最终处理。HttpHandler调用ProcessRequest()方对http请求进行处理,处理完成以后完成以后,再交给HttpModule,然后再由HttpModule将处理完的Http请求信息转交给客户端。处理流程如下图:

      图1:Http请求到达HttpRuntime:

      

      图2:HttpModule与HttpHandler处理流程:

       

    整个Http请求处理流程为:HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->HttpPipeline-->ASPNET_WP.EXE-->

    HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()。

      HttpModule的工作原理:监听HttpRequest请求,同时对HttpRequest增添或者过滤一些内容。HttpModule实现了IHttpModule接口。重写HttpModule的实现即设计一个现实了IHttpModule接口的类。IHttpModule接口包括两个方法:1、Dispose()。2、Init()。具体代码如下:

      

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.Web;
    6
    7 namespace HttpModules
    8 {
    9 public class ValidaterHttpModuleEvents : IHttpModule
    10 {
    11 #region IHttpModule 成员
    12
    13 public void Dispose()
    14 {
    15 throw new NotImplementedException();
    16 }
    17
    18 public void Init(HttpApplication context)
    19 {
    20
    21 context.BeginRequest += new EventHandler(Application_BeginRequest);
    22 context.EndRequest += new EventHandler(context_EndRequest);
    23 }
    24
    25 void context_EndRequest(object sender, EventArgs e)
    26 {
    27 HttpContext.Current.Response.Write("ValidaterHttpModuleEvents EndRequest </br>");
    28 }
    29
    30 #endregion
    31
    32 void Application_BeginRequest(object sender, EventArgs e)
    33 {
    34
    35 HttpApplication application = sender as HttpApplication;
    36 application.CompleteRequest();
    37 //HttpContext.Current.Response.Redirect("http://www.163.com");
    38 application.Context.Response.Write("ValidaterHttpModuleEvents Begin Request </br>");
    39
    40
    41 }
    42 }
    43 }


        然后,在Web.Config的System.Web的httpModules配置节中添加如下配置代码:

      <add name="HttpModule" type="HttpModules.ValidaterHttpModuleEvents,HttpModules"/>

    name可以随便指定,Type由【,】分割为两部分,前一部分指明实现IHttpModule接口类的全名,包括命名空间与类型名,后一部分指明程序集编译成功后的程序集。

        这样我们在浏览器中浏览页面即可看到如下图:

      同样,如果我们在多个类库中以相同的方式重写IHttpModule机制,只需要在httpModules配置节中添加如下配置代码添加相同的配置节即可。

      我在另外一个库中重写的代码如下:

      

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    
    namespace HttpModules2
    {
        public class HttpModulesTest2 : IHttpModule
        {
            #region IHttpModule 成员
    
            public void Dispose()
            {
                
            }
    
            public void Init(HttpApplication context)
            {
                context.BeginRequest += new EventHandler(context_BeginRequest);
                context.EndRequest += new EventHandler(context_EndRequest);
            }
    
            public void context_EndRequest(object sender, EventArgs e)
            {
                HttpContext.Current.Response.Write("HttpModulesTest2 EndRequest  </br>");
            }
    
            
    
            public void context_BeginRequest(object sender, EventArgs e)
            {
                HttpContext.Current.Response.Write("HttpModulesTest2 BeginRequest </br>");
            }
    
            #endregion
        }
    }
    

      然后在配置文件中的配置如下:

      <add name="HttpModule" type="HttpModules.ValidaterHttpModuleEvents,HttpModules"/>
          <add name="HttpModuleTest2" type="HttpModules2.HttpModulesTest2,HttpModules2"/>

        此时的输出如下:

      ValidaterHttpModuleEvents Begin Request
      ValidaterHttpModuleEvents EndRequest
      HttpModulesTest2 EndRequest

      同样:我再用同样的方式重写一个HttpModule,得出的输出结果类似。稍后,我会给出下载代码。

    由此输出结果我得出如下结论:多个HttpModule对Http请求进行处理,只有Web.Config中httpModules配置节的第一个IHttpModule的BeginRequest事件会响应,但是httpModules配置节下的所有IHttpModule实例对象的EndRequest事件都会响应。

      如果大家看看本文上面的链接地址,一定会发现:他说的执行方式是httpModules配置节下的所有重写HttpModule机制的BeginRequest会按照配置顺序执行,然后才是EndRequest也按照配置顺序执行。按照我上面的例子就应该是:

      1、HttpModule.BeginRequest

      2、HttpModuleTest2.BeginRequest

      3、HttpModule.EndRequest

      4、HttpModuleTest2.EndRequest

    而事实上,按照我示例中的输出,却并非如此。

    以上为个人意见。代码下载:http://download.csdn.net/source/3466595

    (博客园上一直不知道在哪上传文件,所以一直都发布在CSDN上。)

    参考资料:

    1、http://hi.baidu.com/5ihuige/blog/item/c1da61a3b9890286461064e6.html

    2、http://www.cnblogs.com/Jax/archive/2007/10/02/912884.html

    以上图片1,图片2,是从以上地址从拷贝下来的。大家可以参见原文。

      

      

  • 相关阅读:
    40个免费flash相册程序
    Web前端技术趋势:HTML5仍不宜用作生产
    推荐25个提高网站可用性和转化率的工具
    14个可以节省你时间的CSS工具
    12个便于web设计及开发的在线工具
    推荐30个国外的精美字体下载网站
    分享10个色彩绚丽的网站
    2010最值得关注的10款小众互联网产品
    Spring RSocket:基于服务注册发现的 RSocket 负载均衡
    在游戏运营行业,Serverless 如何解决数据采集分析痛点?
  • 原文地址:https://www.cnblogs.com/tyb1222/p/2115740.html
Copyright © 2020-2023  润新知