原文地址: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. php中 curl模拟post发送json并接收json(转)

    本地模拟请求服务器数据,请求数据格式为json,服务器返回数据也是json. 由于需求特殊性, 如同步客户端的批量数据至云端, 提交至服务器的数据可能是多维数组数据了.  这时需要将此数据以一定的数据 ...

  2. bootstrap 设置表格固定宽度 内容换行

    在项目中开发的时候用的bootstrap,但是有些表格的内容 会显示的很长 那么我第一时间想到的就是 修改td或者th的width,但是我设置了 之后不起作用 于是百度找到了解决方法: 学习源头: h ...

  3. 阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql

    此教程中使用的相关IP等设置,在你的环境中要做相应修改. 使用之前更新apt-get,因为服务器基本上是一个裸系统 apt-get update;apt-get upgrade; 1 我们使用root ...

  4. java代码从键盘输入n的值,计算1+1/2+1/3+...+1/n的值,,

    总结:谢谢陈勇老师.很棒的指导.超有爱. 总是不思考++++如内存的分析.堆和栈.堆内存里对象,字符串,栈里基本数据类型 来龙去脉,属性方法的调用,都不是很理解.... package com.c2; ...

  5. MySQL的Innodb缓存相关优化

    MySQL的Innodb缓存相关优化 INNODB 状态的部分解释 通过 命令 SHOW STATUS LIKE  'Innodb_buffer_pool_%' 查看  Innodb缓存使用率  (I ...

  6. 关于Unity发布iOS平台代码混淆问题

    之前在越狱手机里找到<永恒战士3>的程序发现是用Unity做的,拷出资源出来看的时候发现里面有游戏程序集,立马抽出来反编译了一下,发现里面的代码只有方法签名,没有方法体,还以为用什么高端混 ...

  7. 第十三章 MySQL用户管理(待续)

    ·············

  8. Bokeh绘图

     http://bokeh.pydata.org/en/latest Bokeh 是一个专门针对Web浏览器的呈现功能的交互式可视化Python库.这是Bokeh与其它可视化库最核心的区别. 专门针对 ...

  9. Python函数的进阶

    一  函数的动态参数 *agrs  位置参数动态传参 *args  接收多个位置参数 def func(*args): print(args) func("女儿国","西 ...

  10. [ShaderStaff] Sprite Outline外轮廓效果

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity5.3.8f1 Unity提供了2D Object Sprite对象,但是没有提供外轮廓Outline效果的支持 ...