ASP.NET使用ashx输出图片
以前我们在.NET里动态输出图片,往往是建一个aspx,把里面的html代码都删光,然后在cs代码里用response输出一个图片类型的stream。之后指定Image控件的url为这个aspx就行。但是,更好的做法是用ashx。
先简单介绍一下ashx:
ashx是ASP.NET里的web handler,用来处理Http请求。因为它不是aspx,所以它无需走aspx的生成过程,避免了事件、控件树等的处理,因此性能比aspx好,并且 编写ashx只需要关心request的处理,不用关心web界面上的表现,有点类似JavaEE里的Servlet。动态生成图片这样的事用ashx做 再好不过啦!
以我网站Web App里二维码生成器为例。原先生成图片的aspx后台代码如下:
protected void Page_Load(object sender, EventArgs e)
{
System.Drawing.Image image = (System.Drawing.Image)Session["tempImg"];
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.ClearContent();
Response.ContentType = "image/Jpeg";
Response.BinaryWrite(ms.ToArray());
image.Dispose();
Session.Clear();
}
现在把它做到ashx里,完整的ashx代码如下:
<%@ WebHandler Language="C#" Class="GetQRImage" %>
using System;
using System.Web;
public class GetQRImage : IHttpHandler, System.Web.SessionState.IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
{
System.Drawing.Image image = (System.Drawing.Image)context.Session["tempImg"];
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
context.Response.ClearContent();
context.Response.ContentType = "image/Jpeg";
context.Response.BinaryWrite(ms.ToArray());
image.Dispose();
context.Session.Clear();
}
public bool IsReusable
{
get
{
return false;
}
}
}
注意:
1. 因为IHttpHandler接口的约定,ashx里必须包含IsReusable的实现
2. 我需要在ashx里读取Session,所以我必须实现IReadOnlySessionState接口。如果要写Session,就要实现IRequiresSessionState接口。
3. ProcessRequest的参数是HttpContext,所以Reponse或者Session什么的请使用context来访问。