原文地址:http://www.cnblogs.com/wujy/archive/2013/08/18/3266009.html

经过前两篇[ASP.NET基础之HttpModule学习]和[ASP.NET基础之HttpContext学习]文章的学习我们对ASP.NET的基础内容有一个比较详细的了解,本文将对第三个比较重要的知识HttpHandler进行学习,将通过一些理论跟实例来演示HttpHandler运用;有部分理论知识来源于网源,希望对您的阅读有所帮助;

一:HttpHandler理论知识

1:IHttpHandler定义了如果要实现一个HTTP请求的处理所必需实现的一些系统约定。HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

2:当一个HTTP请求经同HttpModule容器传递到HttpHandler容器中时,ASP.NET Framework会调用HttpHandler的ProcessRequest成员方法来对这个HTTP请求进行真正的处理。以一个ASPX页面为例,正是在这里一个ASPX页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。对于ASPX页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。HttpHandlerFactory;HttpHandlerFactory,是指当一个HTTP请求到达这个HttpHandler Factory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。针对.aspx在machine.config中是这样定义的:

<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/> 

3:一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。

4:其实我们可以自定义HttpHandler来处理某些特殊文件的请求或者逻辑的实现;自定义HttpHandler必须实现接口IHttpHandler;其中属性IsReusable表示获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。而方法ProcessRequest则是以一个HttpContext的上下文为参数;这些我们就可以操作HttpContext里封装的Request,Response,Server等;

二:HttpHandler之一般程序处理类(Handler.ashx)

1:在我们讲解自定义HttpHandler时,我们首先看下VS里的一般程序处理类(Handler.ashx),在我们平常开发过程中其实已经有应用到一些HttpHandler,比如我们新建一个一般程序处理类时

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web; public class Handler : IHttpHandler { public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
} public bool IsReusable {
get {
return false;
}
} }

上面的代码是增加完一个一般处理程序系统默认为我们增加的内容;以前对HttpHandler不了解,所以也不是很了解为什么会自动增加这样的代码;其实它是实现的IHttpHandler接口,对接口成员的一个实现;

2:若是使用到一般处理程序时有个地方要注意,就是它对Session值的读起时;运用上面的Handler.ashx是读不到Session值;实例如下:

我们定义一个NotSessionHandler.ashx用来读取Session的值:

<%@ WebHandler Language="C#" Class="NotSessionHandler" %>

using System;
using System.Web; public class NotSessionHandler : IHttpHandler { public void ProcessRequest(HttpContext context)
{
Object SessionValue = context.Session["NotSession"];
string Result = string.Empty;
if (SessionValue != null) { Result = SessionValue.ToString(); }
else
{
Result = "没有实现接口;Session的值无法读到";
}
context.Response.ContentType = "text/plain";
context.Response.Write(Result);
} public bool IsReusable {
get {
return false;
}
}
}

首先我们再Default.aspx页面进行写入Session值,并让NotSessionHandler.ashx显示:

    protected void Button4_Click(object sender, EventArgs e)
{
Session["NotSession"] = "踏浪帅";
Response.Redirect("NotSessionHandler.ashx");
}

运行结果如下(从下面不然发现读取失败):

为什么NotSessionHandler.ashx读取不到Session 的值?它不是已经有当前HttpContext上下文?其实NotSessionHandler.ashx还必须实现Session的一个重要接口IRequiresSessionState;其实接口IRequiresSessionState里并没有什么内容,只是一个简单的标识而已;它是存在于System.Web.SessionState内

接着我们实现对上面的NotSessionHandler.ashx进行修改,让它实现接口IRequiresSessionState;

using System;
using System.Web;
using System.Web.SessionState;
public class NotSessionHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
Object SessionValue = context.Session["NotSession"];
string Result = string.Empty;
if (SessionValue != null) { Result = SessionValue.ToString(); }
else
{
Result = "没有实现接口;Session的值无法读到";
}
context.Response.ContentType = "text/plain";
context.Response.Write(Result);
} public bool IsReusable {
get {
return false;
}
}
}

运行结果:

三:自定义HttpHandler

1:自定义一个HttpHandler处理程序只要两步就可以实现了,第一是让类实现接口IHttpHandler,第二就是增加Web.config配置文件;

2:接下来我们将通过一个实例来演示对我们自个建的后缀类型进行访问;

步骤一:我们先建一个类MyHttpHandler类并实现接口IHttpHandler,此处只是显示内容;

using System.Web;
using System.IO;
using System.Text;
public class MyHttpHandler:IHttpHandler
{
public MyHttpHandler()
{ } public bool IsReusable
{
get { return true; }
} public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response; response.Write("这个是自定义的HttpHandler </br>");
response.Write("访问URL地址:" + request.Url.Segments[]+"</br>");
string FileStr = request.PhysicalPath;
if (File.Exists(FileStr))
{
response.Write("以下是文件Cnblogs.wujy的内容 <br/>");
FileInfo fileInfo = new FileInfo(FileStr);
StreamReader reader = new StreamReader(FileStr, Encoding.Default);
string StrLine = string.Empty;
while (!string.IsNullOrEmpty(StrLine = reader.ReadLine()))
{
response.Write(StrLine + "</br>");
}
reader.Close();
}
else
{
response.Write("文件不存在");
}
}
}

步骤二:在站点里我们新建一个Cnblogs.wujy的文件,此处的后缀名为:wujy 它是我自定义的一个后缀;Cnblogs.wujy文件内容:踏浪帅的地址www.cnblogs.com/wujy

步骤三:修改web.config配置;

    <httpHandlers>
<add path="*.wujy" verb="*" type="MyHttpHandler"/>
</httpHandlers>

运行效果如下(如果部署在IIS上可能要对后缀进行映射,在IIS里进行设置,不然这种可能在IIS那就直接访问不了):

上面我们是直接在VS运行时的情况,当我们部署在IIS要进行设置,不然在IIS里访问Cnblogs.wujy就会报下面的错误:

由于我本地的IIS为版7.0所以设置如下(若是IIS5或II6可以在应用程序扩展映射增加后缀):

3:接下来我们将通过一个实例,此实例是在ASP.Net夜话里看到的;实例主要实现一个对站点里的图片进行打水印的功能,这个功能是图片上传后在访问图片时打水印,它其实并不有把水印打在图片上只是访问时才显示出水印,保持图片的原来模样;

步骤一:我们新建一个实现接口IHttpHandler的类WaterMarkHandler:

using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO; /// <summary>
/// 动态给图片添加水印的类
/// </summary>
public class WaterMarkHandler:IHttpHandler
{
public WaterMarkHandler()
{ } #region IHttpHandler 成员
/// <summary>
/// 指示其它请求是否可以使用这个实例,如果是true,则放入池中接受其它请求以提高请求
/// </summary>
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 处理请求
/// </summary>
/// <param name="context">当前HTTP请求的上下文</param>
public void ProcessRequest(HttpContext context)
{
//获取请求的物理图片路径
string imagePath = context.Request.PhysicalPath; Image image = null;
if (File.Exists(imagePath))
{
//定义水印文字
string text = "给图片增加水印[踏浪帅]";
//定义水印文字字体大小
int fontSize = ;
//水印文字字体
Font font = new Font("宋体", fontSize);
//根据图片物理地址加载图片
image = Image.FromFile(imagePath);
Graphics g = Graphics.FromImage(image);
//获取要绘制水印文字所需要的显示区域大小
SizeF size=g.MeasureString(text, font);
if (size.Width > image.Width || size.Height > image.Height)
{
//如果要显示的图片的尺寸都不足以显示按照指定字体来添加水印
//可以减小字体大小或者不添加水印(太小了没办法添加嘛)
}
else//添加水印文字
{
Brush brush = Brushes.Red;
//在图片上添加水印,绘制水印文字在图片的右下角
g.DrawString(text, font, brush, image.Width - size.Width, image.Height - size.Height);
g.Dispose();
}
}
else//如果不存在,指定一个默认图片进行显示
{
imagePath = context.Server.MapPath("~/images/nopic.jpg");
image = Image.FromFile(imagePath);
}
image.Save(context.Response.OutputStream, ImageFormat.Jpeg);//将添加水印的图片输入到当前流中
} #endregion
}

步骤二:修改配置文件web.config(说明针对本站的图片都用上面的处理程序类处理)

    <httpHandlers>
<add path="*.jpg" verb="*" type="WaterMarkHandler"/>
</httpHandlers>

步骤三:我们新建一个页面用来显示图片:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<img src="Image/1.jpg" alt="打水印"/>
</div>
</form>
</body>
</html>

运行查看效果图:

其实我们还有很多在平时开发中可能会用到自定义HttpHandler的功能,比如我们最常用的验证码功能和网站的图片防盗连功能等;

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。  因为,我的写作热情也离不开您的肯定支持。

(转)ASP.NET基础之HttpHandler学习的更多相关文章

  1. ASP.NET基础之HttpHandler学习

    ASP.NET基础之HttpHandler学习 经过前两篇[ASP.NET基础之HttpModule学习]和[ASP.NET基础之HttpContext学习]文章的学习我们对ASP.NET的基础内容有 ...

  2. ASP.NET基础之HttpModule学习

    最近学习WCF知识时看到有关IIS版本的知识,发现对HttpContext,HttpModule,HttpHandler的内容都不是很了解,这三个也是ASP.NET相对基础的内容,晚上特地花点时间针对 ...

  3. ASP.NET基础之HttpContext学习

    一:HttpContext理论知识: 1:HttpContext类它对Request.Respose.Server等等都进行了封装,并保证在整个请求周期内都可以随时随地的调用:为继承 IHttpMod ...

  4. Asp.Net MVC4 + Oracle + EasyUI 学习 序章

    Asp.Net MVC4 + Oracle + EasyUI  序章 -- 新建微软实例 本文链接:http://www.cnblogs.com/likeli/p/4233387.html 1.  简 ...

  5. (转)asp.net基础-HttpModule

    HttpModule是向实现类提供模块初始化和处置事件.当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于H ...

  6. ASP.NET Core on K8S学习初探(3)部署API到K8S

    在上一篇<基本概念快速一览>中,我们把基本的一些概念快速地简单地不求甚解地过了一下,本篇开始我们会将ASP.NET Core WebAPI部署到K8S,从而结束初探的旅程. Section ...

  7. ASP.NET Core on K8S学习初探(2)K8S基本概念快速一览

    在上一篇<单节点环境搭建>中,通过Docker for Windows在Windows开发机中搭建了一个单节点的K8S环境,接下来就是动人心弦的部署ASP.NET Core API到K8S ...

  8. 零基础如何系统学习Java Web

    零基础如何系统学习Java Web?   我来给你说一说 你要下决心,我要转行做开发,这样你才能学成. 你要会打字,我公司原来有一个程序员,打字都是两个手一指禅,身为程序员你一指禅怎么写出的代码,半个 ...

  9. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

随机推荐

  1. MySQL-事务的实现-redo

    MySQL中事务: 事务的实现:      ACID: 原子性(A : Atomicity) 一致性(C : consistency ) 隔离性(I : isolation) 持久性(D : dura ...

  2. 初学者手册-IDEA常用快捷键

    一.快速创建基于某个接口的类(引入相关包) 左键选择接口名称,使用快捷键Alt+enter,然后实现该类 二.打开选中的文件所在的文件夹 点选需要打开的文件,右键菜单,点击“Show in Explo ...

  3. org.apache.hadoop.security.AccessControlException: Permissiondenied: user=liuyingping, access=WRITE,inode="/user/root/output":root:supergroup:drwxr-xr-x

    原因: 权限问题.用户liuyingping没有访问hdfs下文件的权限. 参考:HDFS客户端的权限错误:Permission denied 解决方案(推荐): 在系统的环境变量添加HADOOP_U ...

  4. 1142 Maximal Clique

    题意:给出一个图,定义这样一个结点子集subset,若subset中的任意两结点不都相邻,则称之为Not a Clique:若subset中的任意两结点都相邻,则称之为Clique:若subset中的 ...

  5. JS面向对象编程,对象,属性,方法。

    document.write('<script type="text/javascript" src="http://api.map.baidu.com/api?v ...

  6. Idea 如何设置微软雅黑等其它字体

    使用过idea的同学都知道,idea的功能相对于explise来说,功能太强大了啊~个人感觉,idea真心挺智能的.但是,这里有一个小瑕疵,就是能够设置的字体,有限! 对于用惯了 微软雅黑 字体的人, ...

  7. DDD学习笔录——提炼问题域之有效提炼知识的模型(三)

    方式六:延迟对模型中概念的命名 对领域建模时命名很重要. 因为在不断的知识提炼过程中经常会发现已经被命名的概念与你最初理解的有出入,这时你当初的命名就会变成一个问题.其问题在于  最初选作名称的这个词 ...

  8. MySQL高可用MHA实战

    MySQL高可用架构MHA介绍 简介: MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职 ...

  9. RTMP_EnableWrite(rtmp)

    发布流关键函数: RTMP_EnableWrite(rtmp); 将rtmp设置可写状态,会发出publish指令,否则是play指令:

  10. Zookeeper 基础、工作流、ZAP协议

    ZooKeeper 基础 在深入了解ZooKeeper的运作之前,让我们来看看ZooKeeper的基本概念.[1] 我们将在本章中讨论以下主题:1.Architecture(架构)2.Hierarch ...