`
北极的。鱼
  • 浏览: 152558 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【转】HttpHandler HttpModule入门篇

阅读更多

ASP.Net 处理 Http Request 时,使用 Pipeline (管道)方式,由各个 HttpModule 对请求进行处理,然后到达   HttpHandler HttpHandler 处理完之后,仍经过 Pipeline 中各个 HttpModule 的处理,最后将 HTML 发送到客户端浏览器中。

生命周期中涉及到几个非常重要的对象: HttpHandler HttpModule IHttpHandlerFactory 他们的执行顺序大致的执行过程是这样的:

client 端发送页面请求,被 IIS 的某个进程截获,它根据申请的页面后缀 (.aspx) 不同,调用不同的页面处理程序 (.asp->asp.dll; .aspx->ISAPI.dll) 。而页面处理程序在处理过程中,则要经历 HttpModule HttpHandler 的处理:前者 HttpModule 用于页面处理前和处理后的一些事件的处理,后者 HttpHandler 进行真正的页面的处理。
如前所说, HttpModule 会在页面处理前和后对页面进行处理,所以它不会影响真正的页面请求。通常用在给每个页面的头部或者尾部添加一些信息(如版权声明)等。曾经见过一些免费的空间,我们的页面上传上去后,浏览的时候发现,在每个页面的头部和尾部多了很多小广告 .... 如果理解了 HttpModule 的原理,要做这个就不是很难了 ~


IHttpModule IHttpHandler 的区别整理
1. 先后次序 . IHttpModule, IHttpHandler.   :Module 要看你响应了哪个事件,一些事件是在 Handler 之前运行的,一些是在 Handler 之后运行的
2. 对请求的处理上 :
   IHttpModule
是属于大小通吃类型 , 无论客户端请求的是什么文件 , 都会调用到它 ; 例如 aspx,rar,html 的请求 .
   IHttpHandler
则属于挑食类型 , 只有 ASP.net 注册过的文件类型 ( 例如 aspx,asmx 等等 ) 才会轮到调用它 .
3. IHttpHandler 按照你的请求生成响应的内容, IHttpModule 对请求进行预处理,如验证、修改、过滤等等,同时也可以对响应进行处理

 

ASP.Net 系统本身配置有很多 HttpHandler HttpModule ,以处理 aspx .Net 标准的页面文件,以及这些页面文件中标准的事件处理等。查看

%System%/Microsoft.NET\Framework\v2.0.50727\CONFIG 目录下的   web.config 文件中的 httpHandlers httpModules 节点,可以看到这些配置。如果有兴趣,可以使用 Reflector 查看 .Net 系统中相关的类和方法,了解 .Net 如何处理以及做了什么处理。

.Net 也提供了一套机制来开发自定义的 HttpHandler   HttpModule ,均可以用于对 HttpRequest 的截取,完成自定义的处理。   HttpModule   继承 System.Web.IHttpModule 接口,实现自己的 HttpModule 类。必须要实现接口的两个方法: Init Dispose 。在   Init 中,可以添加需要截取的事件; Dispose 用于资源的释放,如果在 Init 中创建了自己的资源对象,请在 Dispose 中进行释放。

【转自:http://www.cnblogs.com/cyan/archive/2009/02/04/1383580.html

 

namespace MyModule
{

    public class MyHttpModule : IHttpModule
    {

        public MyHttpModule()

        {

        }

        //Init方法用来注册HttpApplication 事件。
        public void Init(HttpApplication r_objApplication)

        {

            r_objApplication.BeginRequest += new EventHandler(this.BeginRequest);

        }

        public void Dispose()

        {

        }

        private void BeginRequest(object r_objSender, EventArgs r_objEventArgs)

        {

            HttpApplication objApp = (HttpApplication)r_objSender;

            objApp.Response.Write("您请求的URL为" + objApp.Request.Path);

        }

    }

} 

 

将编译的 dll 文件拷贝到 web 项目的 bin 目录下,在 web 项目的 web.config 文件 system.web 节点中配置:

 

<httpModules>
      <add name="test" type="MyModule.MyHttpModule,MyHttpModule"/>
</httpModules>

 

 

 

namespace MyHandler
{

    public class MyHttpHandler : IHttpHandler, IRequiresSessionState
    {

        public MyHttpHandler() { }

        public bool IsReusable
        {

            get { return true; }

        }

        public void ProcessRequest(HttpContext context)

        {

            HttpResponse objResponse = context.Response;

            objResponse.Write("This request is handled by MyHttpHandler");

        }

    }

}

 

 

   把编译的 dll 文件拷贝到 web 项目的 bin 目录下。
   
  接下来,这样来测试一下 MyHttpHandler 。我们为 IIS 配置一个以 .cc 为后缀名的文件类型,用我们写的 MyHttpHandler 来处理。
   
  首先,在 IIS 站点的 Configuration 配置里面,添加一个对 .cc 后缀名处理的 Application Extention Mapping 项。     
   
  然后,在 web 项目的 web.config 节点中配置:

 

<httpHandlers>
      <add verb="*" path="*.cc" type="MyHandler.MyHttpHandler,MyHandler"/>
</httpHandlers>

 

    verb 属性配置这个 HttpHandler 处理那些 HTTP 方法,例如 GET POST 等,如果是处理所有方法,就用 * path 属性配置 HttpHandler 对哪些文件进行处理,例如可以是 myfile.cc ,如果是处理所有的 .cc 文件,就用 *.cc
   
  这样,这个站点上所有 .cc 类型文件的访问,都由 MyHttpHandler 处理。使用 http://localhost/ 站点虚拟目录 /a.cc 访问测试站点,可以看到测试效果。当然, a.cc 这个文件在 Web 服务器上是并不存在的。

      HttpHandler 的使用,比较典型的有 .Net Web MVC 开源项目 Maverick Maverick 使用一个 Dispatcher 类对所有的 Http Request 进行截取,他以 .m 作为后缀名向 Web 服务器提交请求,在 Dispatcher 中,将 .m 的后缀去掉,提取 Command Name ,然后以这个 command name 从配置文件中加载处理的 flow ,形成一个 chain ,依次对 chain 上的各个 command view 进行处理,对各个 command   view 的处理结果可能会在 chain 中选择不同的处理分支,每个处理的 Step 中将处理结果的 HTML 写入 Response 的缓存中进行输出。
   
  总体来说, Maverick 的框架架构概念很不错,但也存在明显的缺陷,以后有时间再详细的写写它的架构和需要改进之处。

      总之,将 HttpModule HttpHandler ,以及使用 Ajax 等将客户端进行封装结合起来,能够给 web 项目的开发带来非常大的改善空间。

我们经常看到很多网站访问文章的时候才用的是 ***.html   ***.shtml ( 如本 blog 的日志访问效果 ) ,其时这写文件在服务器上不存在的,那为什么会出现这样的效果呢,是因为 Web 服务器上对 URL 执行了重写,把访问的   URL 根据特定的格式重写成内部访问页面来实现的,它的好处是便于用户理解,同时搜索引擎也能更好地收入你的网站,当然其它的好处也很多,这里不做一一介   绍了。  
本文所讲的是使用 Asp.Net 中的 HttpHandler 实现 URL 重写的,它所实现的原理请看这里,本程序可以处理任何 Url ,因为我在程序中使用了 URL 过虑,只有访问文件名是数字的才进行处理,并指在内部执行一个新的页面,并输出数据,代码如下:

 

public void ProcessRequest(HttpContext Context)
{

    try
    {

    //申明Request    
    HttpRequest Request = Context.Request;

    //取来路Url的绝对路径       
    string Url = Request.Url.AbsolutePath;

    //取访问的Web文件的开始字符间隔数
    int RegStart = Url.LastIndexOf("/") + 1;

    //申明一个确定Web文件名是否全是数字
    Regex Reg = new Regex(@"\d+");

    //用正则表达式进行匹配
    if (Reg.IsMatch(Url, RegStart))
        {
            //如果web文件名是数字,则判定是查询相关文章,执行指定页面
            Context.Server.Execute("~/PermaLink.aspx?id=" + Reg.Match(Url, RegStart).Value);
        }
    }

    catch
    {
        Context.Response.Redirect(Context.Request.Url.ToString());
    }
}

 

当然你首先要做的是先建一个类,并继承自 IHttpHandler ,然后把这段代码拷入,并编译。在 Web 项目中若要使用此功能,需要在 web.config 里面加上如下语句:

 

<httpHandlers>
      <add verb="*" path="*.shtml" type="HttpHandle.UrlRewrite" />
</httpHandlers>

 

同时,还要在 IIS 中对 Web 目进行配置 ,在 Web 项目的属性中,在主目录选项卡里,把执行权限改为 " 脚本和可执行文件 " ,然后打开配置,在应用程序扩展里加上需重写的文件格式的扩展。好了,万事具备,只欠运行了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics