在网站开发中, 经常需要对某一类的资源进行统一处理, 针对这种情况, 我们可以通过创建自定义HTTP处理程序来解决.
如上图所示: IIS对于收到的请求会根据请求的扩展名来进行筛选, 默认情况下, 一些静态资源(如:*.htm、*.html、*.jpg、*.gif等)会由IIS直接处理并返回给浏览器; 而对于另外一些特殊处理的扩展名(如: *.aspx、*.ashx等), 将使用 c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll 将请求传递到网站处理程序. 网站处理程序在web.config中查找到处理该请求的类, 并由该类的对象处理该类请求.
自定义HTTP处理程序的步骤:
1. 自定义类实现IHttpHandler接口, 在该类中利用HttpContext对象处理收到的请求.
在处理请求的类中, 可以自定义请求的扩展名(可以为任意名字), 也可以实现IHttpAsyncHandler接口来异步的处理Http请求.
如果要对同一类文件的不同请求方式(如:GET方式或POST方式)分别处理, 可以通过实现了IHttpHandlerFactory接口的自定义类来达到目的, 在工厂类中分别为GET请求和POST请求实例化不同的对象(注意类型名必须大写).
2. 修改web.config文件, 添加处理程序的映射. 例如:
<system.web>
<httpHandlers>
<!—verb=’*’表示所有请求-->
<add verb=”GET” path=” *.rfi” type=”System.Rotate.RotateImageHandler” />
</HttpHandlers>
</system.web>
3. 在IIS中, Web程序的属性中, “主目录” ---> “应用程序设置” --> “配置”中添加相应的后缀名. 注意: “检查文件是否存在” 的勾一定要去掉.
注: IHttpHandler接口中, 有两个成员: IsReusable属性表示该对象是否重用, 通常返回false; ProcessRequest是处理请求的方法.
//RotateImage.cs
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace System.Rotate
{
///<summary>
/// Summary description for RotateImage
///</summary>
publicclass RotateImageHandler : IHttpHandler //自定义请求处理程序必须实现的接口, 然后修改配置文件
{
public RotateImageHandler()
{
//
// TODO: Add constructor logic here
//
}
#region IHttpHandler Members
publicbool IsReusable
{
get { returntrue; }
}
publicvoid ProcessRequest(HttpContext context)
{
//throw new NotImplementedException();
//这里写请求的处理过程
context.Response.ContentType ="image/jpeg";
string virtualpath = context.Request.Path;
string rfipath = context.Server.MapPath(virtualpath); //找到实际路径
string jpgpath = rfipath.Replace(".rfi", ".jpg"); //获得实际jpg文件位置
System.Drawing.Image img =new System.Drawing.Bitmap(jpgpath);
double width = (img.Height/(double)img.Width) * img.Height *0.2;
double height = (img.Height / (double)img.Width) * img.Width *0.2;
System.Drawing.Image thumbimg = img.GetThumbnailImage((int)width, (int)height, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
thumbimg.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipXY);
//保存到浏览器输出流
thumbimg.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
#endregion
bool ThumbnailCallback()
{
returnfalse;
}
}
}
//default.aspx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>原始图片</h1>
<img src= "images/DSC03012.JPG" alt="Origin" width="600" height="480"/>
<hr />
<h1>旋转后的图片</h1>
<img src="images/DSC03012.rfi"alt="dealed"/>
</div>
</form>
</body>
</html>
//web.config
<httpHandlers>
<!--自定义请求处理的类型-->
<add verb="GET" path="*.rfi" type="System.Rotate.RotateImageHandler"/>
</httpHandlers>
</system.web>
还有个特殊的Handler --- WebResource.axd, 这个特殊的处理程序专门用来从程序集中提取资源, 返回给客户端. 注意: 它的名字是固定的, 不能修改.
AssemblyResourceLoader类是一个实现了IHttpHandler的处理程序, 允许我们在页面或者控件中取得嵌入在程序集中的资源, 如脚本、图片和数据文件等. 该处理程序通过 GetWebResourceUrl 方法生成Url来处理请求并返回资源(直接通过Web返回资源).
//Samples.AspNet.CS.Controls为命名空间, 而script_include.js是脚本资源名称
using system;
[assembly: WebResource("Samples.AspNet.CS.Controls.script_include.js","application/x-javascript")]
namespace Samples.AspNet.CS.Controls
{
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
publicclass ClientScriptResourceLabel
{
//这里编写代码
publicstring GerResourceUrl()
{
//嵌入在程序集中的资源名称
string rsname ="Samples.AspNet.CS.Controls.script_include.js";
//获取一个定义在包含资源的程序集中的类的类型
Type rstype =typeof(ClientScriptResourceLabel);
//取得ClientScripManager的引用
ClientScriptManager cs = Page.ClientScript;
//获取一个可以获取资源的Url地址
ResourcePath.InnerHtml = cs.GetWebResourceUrl(rstype, rsname);
//返回的Url的格式如下:
//Webesource.axd?d=<encryped identifier>&t=<time stamp value>, ,encryped identifier表示唯一的标志请求资源, time stamp value是一个来自于被请求的程序集的时间戳
}
}
}