ASP.NET基础之HttpHandler学习

经过前两篇[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[2]+"</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 = 12;
//水印文字字体
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基础

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

  1. (转)ASP.NET基础之HttpHandler学习

    原文地址:http://www.cnblogs.com/wujy/archive/2013/08/18/3266009.html 经过前两篇[ASP.NET基础之HttpModule学习]和[ASP. ...

  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. POJ1135_Domino Effect(最短)

    Domino Effect Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8224   Accepted: 2068 Des ...

  2. Microsoft dotnetConf 2015

    Microsoft dotnetConf 2015 一些整理   dotnetConf 2015 直播计划: 第一天 (10 个主讲) - .NET Product Teams 主讲人为 .NET 产 ...

  3. C++外观设计模式模式(三)

    3.外观模式总结 引入了外观类.解除了客户类与子系统的耦合性.客户类不须要直接操作子系统,而是由外观类负责处理,对client而言是透明的,客户类仅仅须要操作外观类就能够了,符合"迪迷特法则 ...

  4. Errors occurred during the build. Errors running builder &#39;JavaScript Validator&#39; on

    eclipse又一次编译时候就会报错Errors occurred during the build. Errors running builder 'JavaScript Validator' on ...

  5. NET 平台下的插件化开发内核

    .NET 平台下的插件化开发内核(Rabbit Kernel)   每个程序猿都有一个框架梦,曾经在2013年8月15日写过一篇“Koala Framework是什么?我为什么要写这个框架?”的文章, ...

  6. IIS 7.5 使用URL Rewrite模块简单设置网页跳转

    原文 IIS 7.5 使用URL Rewrite模块简单设置网页跳转 我们都知道Apache可以在配置文件里方便的设置针对网页或网站的rewrite,但是最近接手了一组IIS服务器,发现这货简单的没有 ...

  7. IIS7 URL Rewrite 用法实例

    原文:IIS7 URL Rewrite 用法实例 很友好的URL地址,使访问的人很容易记住.要求你的用户记住" http://www.contoso.com/article.aspx?id= ...

  8. ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上

    原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...

  9. apache启动报错:the requested operation has failed解决办法

    原因一:80端口占用 例如IIS,另外就是迅雷.我的apache服务器就是被迅雷害得无法启用! 原因二:软件冲突 装了某些软件会使apache无法启动如Dr.com 你打开网络连接->TcpIp ...

  10. Linux Kernel的Makefile与Kconfig文件的语法

    https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt Introduction ------------ The c ...