(转)ASP.NET基础之HttpHandler学习
原文地址: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学习的更多相关文章
- ASP.NET基础之HttpHandler学习
ASP.NET基础之HttpHandler学习 经过前两篇[ASP.NET基础之HttpModule学习]和[ASP.NET基础之HttpContext学习]文章的学习我们对ASP.NET的基础内容有 ...
- ASP.NET基础之HttpModule学习
最近学习WCF知识时看到有关IIS版本的知识,发现对HttpContext,HttpModule,HttpHandler的内容都不是很了解,这三个也是ASP.NET相对基础的内容,晚上特地花点时间针对 ...
- ASP.NET基础之HttpContext学习
一:HttpContext理论知识: 1:HttpContext类它对Request.Respose.Server等等都进行了封装,并保证在整个请求周期内都可以随时随地的调用:为继承 IHttpMod ...
- Asp.Net MVC4 + Oracle + EasyUI 学习 序章
Asp.Net MVC4 + Oracle + EasyUI 序章 -- 新建微软实例 本文链接:http://www.cnblogs.com/likeli/p/4233387.html 1. 简 ...
- (转)asp.net基础-HttpModule
HttpModule是向实现类提供模块初始化和处置事件.当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于H ...
- ASP.NET Core on K8S学习初探(3)部署API到K8S
在上一篇<基本概念快速一览>中,我们把基本的一些概念快速地简单地不求甚解地过了一下,本篇开始我们会将ASP.NET Core WebAPI部署到K8S,从而结束初探的旅程. Section ...
- ASP.NET Core on K8S学习初探(2)K8S基本概念快速一览
在上一篇<单节点环境搭建>中,通过Docker for Windows在Windows开发机中搭建了一个单节点的K8S环境,接下来就是动人心弦的部署ASP.NET Core API到K8S ...
- 零基础如何系统学习Java Web
零基础如何系统学习Java Web? 我来给你说一说 你要下决心,我要转行做开发,这样你才能学成. 你要会打字,我公司原来有一个程序员,打字都是两个手一指禅,身为程序员你一指禅怎么写出的代码,半个 ...
- ASP.NET MVC Web API 学习笔记---第一个Web API程序
http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...
随机推荐
- bzoj 3612 [Heoi2014]平衡——整数划分(dp)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3612 因为力矩的缘故,变成了整数划分. 学习到了整数划分.就是那个图一样的套路.https: ...
- 在laravel中使用支付宝手机网站支付 和 支付宝退款
1.在蚂蚁金服开放平台中申请对应的应用,并根据提示进行签约 2.给对应的应用信息 生成私钥和公钥(私钥会保存在本地,公钥会放在对应的应用信息中) 3.下载手机网站支付 对应的php sdk 4.将sd ...
- GOF23设计模式之单例模式(singleton)
一.单例模式概述 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. 由于单例模式只生成一个实例,减少了系统性能开销.所以当一个对象的产生需要比较多的资源时,如读取配置.产生其他依赖对象时, ...
- PHP面向对象深入研究之【高级特性】
静态属性 <?php class StaticExample { static public $aNum = 0; // 静态共有属性 static public function sayHel ...
- Cassandra学习五 使用Key的正确姿势
NoSQL一般是反范式的,比如提倡数据冗余,使得不至于写出非常复杂的SQL语句. Cassandra之中一共包含下面5中Key: Primary Key: 用来获取某一行的数据,可以是一列或多列 ...
- burpsuite扫描web目录
1.进行抓包 2.将其发送到lntruder 3.使用替换脚本替换掉/ 4.替换 5.替换结果 6.将多余的$$删除,在/后面添加$$ //$$就是payload 7.测试结果 替换脚本代码: ...
- Python图片转字符画
PIL安装很麻烦,推荐下载exe直接安装 PIL官网:http://pythonware.com/products/pil/ 但现在里面下载链接访问不了,我把32位和64位版本上传到博客园以供下载 P ...
- MAPREDUCE原理篇2
mapreduce的shuffle机制 概述: mapreduce中,map阶段处理的数据如何传递给reduce阶段,是mapreduce框架中最关键的一个流程,这个流程就叫shuffle: shuf ...
- Java微信公众平台开发【番外篇】(七)--公众平台测试帐号的申请
转自:http://www.cuiyongzhi.com/post/45.html 前面几篇一直都在写一些比较基础接口的使用,在这个过程中一直使用的都是我个人微博认证的一个个人账号,原本准备这篇是写[ ...
- django -- url 的 name 属性
在html的form中使用给url定义的name值,可以在修改url时不用在修改form的src. urls.py from django.conf.urls import url from myte ...