通过前两篇[ASP.NET基础之HttpModule学习]和[ASP.NET基础之HttpContext学习]文章的学习咱们对ASP.NET的基础内容有一个比较详细的了解,本文将对第三个比较重要的知识HttpHandler进行学习,将经过一些理论跟实例来演示HttpHandler运用;有部分理论知识来源于网源,但愿对您的阅读有所帮助;html
一:HttpHandler理论知识git
1:IHttpHandler定义了若是要实现一个HTTP请求的处理所必需实现的一些系统约定。HttpHandler与HttpModule不一样,一旦定义了本身的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。github
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中是这样定义的:web
<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接口,对接口成员的一个实现;ui
2:如果使用到通常处理程序时有个地方要注意,就是它对Session值的读起时;运用上面的Handler.ashx是读不到Session值;实例以下:spa
咱们定义一个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的功能,好比咱们最经常使用的验证码功能和网站的图片防盗连功能等;
若是,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。 由于,个人写做热情也离不开您的确定支持。
感谢您的阅读 [源代码下载]
最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,天天都会更新一些深度内容,在这里若是你感兴趣也能够关注一下(嘿对美女跟知识感兴趣),固然能够关注后输入:github 会有个人微信号,若是有问题你也能够在那找到我;固然不感兴趣无视此信息;