1、HttpModule和HttpHandler
ASP.NET在处理HTTP请求时有两个核心的机制HttpModule和HttpHandler。
HttpModule:实际上,当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter(过滤器)的作用。
HttpHandler:HttpHandler是HTTP请求的真正处理中心。正是在这个HttpHandler容器中,ASP.NET才真正地对客户端请求的服务器页面做出编译和执行,并将处理后的信息附加在HTTP请求信息流中再次返回到HttpModule中。这时候HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。
下面以两个实例来讲解HttpHandler的使用
2、封面数字水印的实现
2.1 创建CoverHandler类
首先创建CoverHandler类,并实现IHttpHandler接口。在默认情况下,该类添加在App_Code目录下。
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
/// <summary>
/// 映射文件后缀名方式的数字水印
/// </summary>
public class CoverHandler : IHttpHandler
{
private const string WATERMARK_URL = "/images/WaterMark.jpg"; //水印图片
private const string DEFAULTIMAGE_URL = "/images/default.jpg"; //默认图片
public void ProcessRequest(HttpContext context)
{
System.Drawing.Image cover;
//判断请求的物理路径中,是否存在文件
if (File.Exists(context.Request.PhysicalPath))
{
//加载图片文件
cover = Image.FromFile(context.Request.PhysicalPath);
//加载水印文件
Image watermark = Image.FromFile(context.Request.MapPath(WATERMARK_URL));
//实例化画布
Graphics g = Graphics.FromImage(cover);
//在cover上绘制水印
g.DrawImage(watermark, new Rectangle(cover.Width - watermark.Width, cover.Height - watermark.Height, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel);
//释放画布
g.Dispose();
//释放水印图片
watermark.Dispose();
}
else
{
//加载默认图片
cover = Image.FromFile(context.Request.MapPath(DEFAULTIMAGE_URL));
}
//设置输出格式
context.Response.ContentType = "image/jpeg";
//将图片存入输入流
cover.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
cover.Dispose();
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
2.2 修改配置文件
要捕获封面图片的访问请求,我们在web.config中添加如下代码。
<httpHandlers>
<add verb="*" path="/images/BookCovers/*.jpg,/images/BookCovers/*.png" type="CoverHandler" />
</httpHandlers>
其中各项属性代表的含义如下:
verb:代表谓词(比如GET、POST、FTP等)列表,又称动词列表。可以写作“GET,POST”。“*”为通配符,此处标识所有的请求。
path:访问路径,此处标示所有访问“/images/BookCovers/*.jpg,/images/BookCovers/*.png”路径的请求都将交给CoverHandler类进行处理。
type:指定逗号分隔的类/程序集组合。ASP.NET首先在应用程序的专用\Bin目录中搜索程序集DLL,然后在系统程序集缓存中搜索,这里指定的CoverHandler是我们将要编译的HttpHandler程序。
2.3 注意事项
如果在IIS上运行,则要“添加应用程序扩展名映射”,扩展名为:jpg
3、 图片防盗链的实现
3.1 创建AntiHotlinkHandler类
创建CoverHandler类,并实现IHttpHandler接口。
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
/// <summary>
/// 图片防盗链
/// </summary>
public class AntiHotlinkHandler : IHttpHandler
{
private const string DEFAULTIMAGE_URL = "/images/default.jpg"; //默认图片
public void ProcessRequest(HttpContext context)
{
Uri u = context.Request.UrlReferrer;//访问来源地址
string ip = context.Request.UserHostAddress;//访问来源IP
string serverHost = context.Request.Url.Host;//当前访问主机地址
string localIP = System.Configuration.ConfigurationManager.AppSettings["LocalIP"];
if (u == null || u.Host.ToLower() != serverHost.ToLower() || ip != localIP)
{
context.Response.WriteFile(DEFAULTIMAGE_URL);
}
else
{
context.Response.WriteFile(context.Request.PhysicalPath);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
2.2 修改配置文件
<appSettings>
<add key="LocalIP" value="127.0.0.1"/>
</appSettings>
<httpHandlers>
<add verb="*" path="/images/BookCovers/*.jpg,/images/BookCovers/*.png" type="AntiHotlinkHandler" />
</httpHandlers>