什么是HttpHandler
什么是HttpHandler一、HttpHandler简介
HttpHandler是asp.net真正处理Http请求的地方。在这个HttpHandler容器中,ASP.NET Framework才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。
IHttpHandler在MSDN中的定义:使用自定义的HTTP处理程序同步处理HTTP Web请求而实现的协定。(注意:这里写的很清楚,是同步HTTP请求。如果是异步的话就要使用IHttpAsyncHandler接口)。他包含一个属性IsReusable,用于获取当前IHttpHandler实例是否可用,一般设置为true。一个方法ProcessRequest(HttpContext context),进行实际的操作过程。
HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。
二、IHttpHandler如何处理HTTP请求
当一个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请求。
一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。
三、HttpHandler实例
1.访问者信息:
先新建名为 访问者信息。ashx的文件
<%@ WebHandler Language="C#" Class="访问者信息" %>
using System;
using System.Web;
public class 访问者信息 : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "image/JPEG";
using(System.Drawing.Bitmap bitmap=new System.Drawing.Bitmap(350,300))
{
using(System.Drawing.Graphics g=System.Drawing.Graphics.FromImage(bitmap))
{
g.DrawString("IP:"+context.Request.UserHostAddress,new System.Drawing.Font("宋体",30),System.Drawing.Brushes.Red,0,0);
g.DrawString("操作系统:" + context.Request.Browser.Platform, new System.Drawing.Font("宋体", 30), System.Drawing.Brushes.Red, 0, 50);
g.DrawString("浏览器版本:" + context.Request.Browser.Platform, new System.Drawing.Font("宋体", 30), System.Drawing.Brushes.Red, 0, 100);
}
bitmap.Save(context.Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
public bool IsReusable {
get {
return false;
}
}
}
执行后结果为
IP:127.0.0.1
操作系统:Win7
浏览器版本:IE9
2.HttpHandler实现文件下载
如果HttpHandler 输出的是html、txt、jpeg等类型的信息,那么浏览器会直接显示,如果希望弹出保存对话框,则需要添加
Header:string encodeFileName=HttpUtility.UrlEncode("XXX。txt");
Response.AddHeader("Content-Disposition",string.Format("attachment;filename=\"{0}\"",encodeFileName));
其中filename 后为编码后的文件名。filename段为建议的保存文件名
新建名为 Download。ashx文件
<%@ WebHandler Language="C#" Class="Download" %>
using System;
using System.Web;
public class Download : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "image/JPEG";
string filename=HttpUtility.UrlEncode("AAAA。jpg");//url编码,防止乱码
context.Response.AddHeader("Content-Disposition", "attachment;filename="+filename);
context.Response.WriteFile("AAAA。jpg");
}
public bool IsReusable {
get {
return false;
}
}
}
动态输出的用处:不用再把资源保存到磁盘上在输出(不会有文件重名的问题,文件不生成在服务器端。)
3、生成验证码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;
namespace MyHttpHandler
{
/// <summary>
/// 验证码Handler
/// </summary>
public class ValidateCodeHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/gif";
//建立Bitmap对象,绘图
Bitmap basemap = new Bitmap(200, 60);
Graphics graph = Graphics.FromImage(basemap);
graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);
Font font = new Font(FontFamily.GenericSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel);
Random r = new Random();
string letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
string letter;
StringBuilder s = new StringBuilder();
//添加随机的五个字母
for (int x = 0; x < 5; x++)
{
letter = letters.Substring(r.Next(0, letters.Length - 1), 1);
s.Append(letter);
graph.DrawString(letter, font, new SolidBrush(Color.Black), x * 38, r.Next(0, 15));
}
//混淆背景
Pen linePen = new Pen(new SolidBrush(Color.Black), 2);
for (int x = 0; x < 6; x++)
graph.DrawLine(linePen, new Point(r.Next(0, 199), r.Next(0, 59)),
new Point(r.Next(0, 199), r.Next(0, 59)));
//将图片保存到输出流中
basemap.Save(context.Response.OutputStream, ImageFormat.Gif);
//context.Session["CheckCode"] = s.ToString();
//如果没有实现IRequiresSessionState,则这里会出错,也无法生成图片
context.Response.End();
}
public bool IsReusable
{
get { return true; }
}
}
}
把下面的项加到web.config中的httphandler节点中:
<add verb="*" path="validatevode" type="MyHttpHandler.ValidateCodeHttpHandler,MyHttpHandler"/>
访问validatevode时:
4、图片防盗链应用
有时我们自己web站点中的图片不想被其他站点引用,或者不想让人知道图片地址后直接通过浏览器访问,这就是图片的防盗链。下面是通过HttpHandler实现的图片防盗链:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace MyHttpHandler
{
/// <summary>
/// 图片防盗链HttpHandler
/// </summary>
public class PictureHttpHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
//站点的域名
string myDomain = "localhost";
if (context.Request.UrlReferrer == null ||
context.Request.UrlReferrer.Host.ToLower().IndexOf(myDomain) < 0)
{
//如果是通过浏览器直接访问或者是通过其他站点访问过来的,则显示“资源不存在”图片
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile(context.Request.PhysicalApplicationPath+"/images/noimg。jpg");
}
标签: