1 、概述

说明:HttpHandler是一个HTTP请求的真正处理中心。在HttpHandler容器中,ASP.NET Framework才调用HttpHandler的ProcessRequest成员方法来对这个HTTP请求进行真正的处理,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。

2、举例

以一个aspx页面为例,正是在HttpHandler这里,一个aspx页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。当然,对于aspx页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。当一个HTTP请求到达这个HttpHandlerFactory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。 一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。

3、HttpHandler

(1)实现HttpHandler,必须继承自IHttpHandler接口。下面是这个接口的定义:

  1. using System;
  2.  
  3. namespace System.Web
  4.  
  5. {
  6.  
  7.     public interface IHttpHandler
  8.  
  9.     {
  10.  
  11.         //  其他Request是否可以使用IHttpHandler
  12.  
  13.         bool IsReusable { get; }
  14.  
  15.         //  处理HttpRequest
  16.  
  17.         void ProcessRequest(HttpContext context);
  18.  
  19.     }
  20.  
  21. }

(2)自定义HttpHandler

新建一个网站,default.aspx页面:default.aspx.cs:

  1. using System;
  2.  
  3. using System.Collections.Generic;
  4.  
  5. using System.Linq;
  6.  
  7. using System.Web;
  8.  
  9. using System.Web.UI;
  10.  
  11. using System.Web.UI.WebControls;
  12.  
  13. namespace WebApplication1
  14.  
  15. {
  16.  
  17.     public partial class _Default : System.Web.UI.Page
  18.  
  19.     {
  20.  
  21.         protected void Page_Load(object sender, EventArgs e)
  22.  
  23.         {
  24.  
  25.             Response.Write("<br/>来自Default.aspx页面<br/>");
  26.  
  27.         }
  28.  
  29.     }
  30.  
  31. }
  32.  

新添一个类库MyHandler,添加一个类如下:

  1. using System;
  2.  
  3. using System.Web;
  4.  
  5. using System.Web.SessionState;
  6.  
  7. namespace WebApplication1
  8.  
  9. {
  10.  
  11.     public class MyTestHandler : IHttpHandler, IRequiresSessionState
  12.  
  13.     {
  14.  
  15.         public bool IsReusable { get { return true; } }
  16.  
  17.         public void ProcessRequest(HttpContext context)
  18.  
  19.         {
  20.  
  21.             context.Response.Write("<h3><b>This is a HttpHandler Test</b></h3>");
  22.  
  23.             context.Session["Test"] = "<h3><span style=\"color:blue;\">在HttpHandler容器中调用Session</span></h3>";
  24.  
  25.             context.Response.Write(context.Session["Test"]);
  26.  
  27.         }
  28.  
  29.     }
  30.  
  31. }
  32.  

(3)配置文件
      在web.config文件的system.web节点下,添加:

  1.       <add verb="*" path="*.aspx" type="WebApplication1.MyTestHandler, WebApplication1" />

(4)注意

<1>、.NET为asp.net提供了很多系统默认HttpHandler类,用来适应不同类型的HttpRequest。比如aspx,在machine.config中是这样定义的:   
        <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
这就说明遇到aspx的Request请求,asp.net会将其交给System.Web.UI.PageHandlerFactory的HttpHandler类来处理。
<2>、如果自己定义了新的HttpHandler,而且在web.config中指定,则系统只会使用这个新的HttpHandler,而不再使用原先默认的或者指定的.

4、HttpHandlerFactory

ASP.NET Framework实际不直接将相关的页面资源HTTP请求定位到一个其内部默认的IHttpHandler容器之上,而定位到了其内部默认的IHttpHandler工厂上。IHttpHandler工厂的作用是对IHttpHandler容器进行调度和管理,这样做的优点是大大增强了系统的负荷性,提升了效率。

(1)IHttpHandlerFactory接口
IHttpHandlerFactory接口包含两个方法:GetHandler方法返回实现IHttpHandler接口的类的实例,ReleaseHandler方法使工厂可以重用现有的处理程序实例。

  1. using System;
  2.  
  3. using System.Web;
  4.  
  5. namespace System.Web.UI
  6.  
  7. {
  8.  
  9.     public class PageHandlerFactory : System.Web.IHttpHandlerFactory2, IHttpHandlerFactory
  10.  
  11.     {
  12.  
  13.         protected internal PageHandlerFactory();
  14.  
  15.         public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path);
  16.  
  17.         public virtual void ReleaseHandler(IHttpHandler handler);
  18.  
  19.     }
  20.  
  21. }

(2) 实现一个简单的HttpHandler工厂
类库新添一个文件MyHandlerFactor.cs:

  1. using System;
  2.  
  3. using System.Collections.Generic;
  4.  
  5. using System.Linq;
  6.  
  7. using System.Web;
  8.  
  9. namespace WebApplication1
  10.  
  11. {
  12.  
  13.     public class MyHandlerFactory : IHttpHandlerFactory
  14.  
  15.     {
  16.  
  17.         public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
  18.  
  19.         {
  20.  
  21.             string fileName = url.Substring(url.LastIndexOf("/") + 1);
  22.  
  23.             string objName = fileName.Substring(0, fileName.IndexOf("."));
  24.  
  25.             string className = "WebApplication1." + objName;
  26.  
  27.             object objHandler = null;
  28.  
  29.             try
  30.  
  31.             {
  32.  
  33.                 // 采用动态反射机制创建相应的IHttpHandler实现类。
  34.  
  35.                 objHandler = Activator.CreateInstance(Type.GetType(className));
  36.  
  37.                 context.Response.Write(className);
  38.  
  39.             }
  40.  
  41.             catch (Exception e)
  42.  
  43.             {
  44.  
  45.                 throw new HttpException("工厂不能为类型" + objName + "创建实例。", e);
  46.  
  47.             }
  48.  
  49.             return (IHttpHandler)objHandler;
  50.  
  51.         }
  52.  
  53.         public void ReleaseHandler(IHttpHandler handler)
  54.  
  55.         {
  56.  
  57.         }
  58.  
  59.     }
  60.  
  61.     public class Handler1 : IHttpHandler
  62.  
  63.     {
  64.  
  65.         public bool IsReusable { get { return true; } }
  66.  
  67.         public void ProcessRequest(HttpContext context)
  68.  
  69.         {
  70.  
  71.             context.Response.Write("<br/>这是来自于MyHandlerFactory里的处理.<br/>");
  72.  
  73.             context.Response.Write("<h3>来自Handler1的信息.</h3>");
  74.  
  75.         }
  76.  
  77.     }
  78.  
  79.     public class Handler2 : IHttpHandler
  80.  
  81.     {
  82.  
  83.         public bool IsReusable { get { return true; } }
  84.  
  85.         public void ProcessRequest(HttpContext context)
  86.  
  87.         {
  88.  
  89.             context.Response.Write("<br/>这是来自于MyHandlerFactory里的处理.<br/>");
  90.  
  91.             context.Response.Write("<h3>来自Handler2的信息.</h3>");
  92.  
  93.         }
  94.  
  95.     }
  96.  
  97. }
  98.  
  1.    <add verb="*" path="Handler1.aspx" type="WebApplication1.MyHandlerFactory,WebApplication1"/>
  2.  
  3.    <add verb="*" path="Handler2.aspx" type="WebApplication1.MyHandlerFactory,WebApplication1"/>

到这里,针对Handler1.aspx和Handler2.aspx两个页面的http请求我们就通过HttpHandler工厂处理好了。

5、HttpHandler和HttpModule的区别

主要有两点:
(1)先后次序.先IHttpModule,后IHttpHandler,IHttpHandler处理结束后再交给IHttpModule;
(2)对请求的处理上:
        IHttpModule是属于大小通吃类型,无论客户端请求的是什么文件,都会调用到它;例如aspx,html,rar的请求;
        IHttpHandler则属于挑食类型,只有asp.net注册过的文件类型(例如aspx,ascx,asmx等等)才会轮到调用它。

【IHttpHandler】了解 IHttpHandler的更多相关文章

  1. 【ASP.NET】IHttpHandler和IHttpModule

    上篇文章我们主要讲了HttpApplicatiion管道事件,那么我么如何处理这些管道事件呢,以及请求在ASP.NET是如何执行的呢,我们来了解一下IHttpHandler和IHttpModule 引 ...

  2. 扩展IHttpHandler

    前面提到当请求进入到IIS,IIS转发给ISAPI后会根据文件的后缀名来决定将请求转发给对应的处理程序进行处理,当然一大部分的处理都是交给了AspNet_ISAPI 了.但是,AspNet_ISAPI ...

  3. ASP.NET MVC 利用IRouteHandler, IHttpHandler实现图片防盗链

    你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...

  4. 在IHttpHandler中获取session

    因为业务要异步通过IHttpHandler获得数据,但还要根据当前登录人员的session过滤,因此要在在IHttpHandler中获取session 方法是HttpHandler容器中如果需要访问S ...

  5. IHttpHandler给图片加水印

    /// <summary> /// WaterMarkHandlher 的摘要说明 /// </summary> public class WaterMarkHandlher ...

  6. IHttpHandler防止图片链接被盗用

    public class JpegHandler : IHttpHandler { public bool IsReusable { get { return true; } } public voi ...

  7. asp.net Web.config 在不同版本的IIS配置的IHttpHandler的访问路径,以及经典模式和集成模式不同的配置

    如果IIS7.0使用.net4.0以上版本的框架,<system.web>中的httpHandlers节点就没有用了,而应该使用微软专为.net4.0以上版本设计的新节点<syste ...

  8. 【IHttpHandler】ASP.NET 生命周期

    对由 Microsoft® Internet 信息服务 (IIS) 处理的 Microsoft® ASP.NET 页面的每个请求都会被移交到 ASP.NET HTTP 管道.HTTP 管道由一系列托管 ...

  9. 【IHttpHandler】使用IHttpHandler防盗链

    防盗链的原理,从图片请求的URL地址上判断是否是我们自己网站上的域名,如果不是,恭喜,你的图片已经被盗链了! 那么我来介绍下图片放盗链的一个方法 首先,添加个httpHandlers请求,webcon ...

  10. 【IHttpHandler】HttpModule,HttpHandler,HttpHandlerFactory简单使用

    这三个对象我们在开发Asp.net程序时经常会用到,似乎很熟悉,但有时候又不太确定.本文通过一个简单的例子来直观的比较一下这三个对象的使用. HttpModule:Http模块,可以在页面处理前后.应 ...

随机推荐

  1. 分页写入文件,第二次分页前一定要关闭IO流啊。。否则文件写不全。。- -粗心

  2. 【JavaScript】微信适配的Head

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <me ...

  3. Redis 发布/订阅机制原理分析

    Redis 通过 PUBLISH. SUBSCRIBE 和 PSUBSCRIBE 等命令实现发布和订阅功能.   这些命令被广泛用于构建即时通信应用,比如网络聊天室(chatroom)和实时广播.实时 ...

  4. js实现的新闻列表垂直滚动实现详解

    js实现的新闻列表垂直滚动实现详解:新闻列表垂直滚动效果在大量的网站都有应用,有点自然是不言而喻的,首先由于网页的空间有限,使用滚动代码可以使用最小的空间提供更多的信息量,还有让网页有了动态的效果,更 ...

  5. [ActionScript 3.0] AS3.0 获取文本的明暗度

    /** * 获取文字的明暗值 * @param t 文字 * @return Number */ function getDensity(t:String):Number { var ttf:Text ...

  6. 异步任务神器 Celery 简明笔记

    转自:http://www.jianshu.com/p/1840035cb510 异步任务 异步任务是web开发中一个很常见的方法.对于一些耗时耗资源的操作,往往从主应用中隔离,通过异步的方式执行.简 ...

  7. [SQL] 不合并重复数据 union all

    select * from A union select * from B --不合并重复行 select * from A union all select * from B --如果要对字段进行排 ...

  8. Mingyang.net:Controller必需是public吗?

    通常定义Controller时一般都定义成public: package net.mingyang.modules.system; @Controller @RequestMapping(" ...

  9. SELinux配置不当导致vsftpd系统用户不能登陆

    1.测试是否是SELinux配置不当导致的: setenforce 0 再次登陆ftp,正常,说明是SELinux配置不当导致.还原配置 setenforce 1 2.查看配置: getsebool ...

  10. [ZOJ 1011] NTA (dfs搜索)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1011 题目大意:在一棵树上,给你起始状态,问你能否到达终止状态. ...