ashx文件和HttpHandler
ashx 文件用于写web handler的。.ashx必须包含IsReusable. 如下例所示。}.ashx比.aspx的好处在与不用多一个html 注意了VS2005中Web应用程序项目模板里的Generic Handler 项,发现它是一个.ashx文件,实际上它是一个HttpHandler。利用.ashx文件是一个更好的方法,这个文件类似于.aspx文件,可以通过它来调用HttpHandler类,从而免去了普通.aspx页面的控件解析以及页面处理的过程。然后在同目录下,使用解决方案资源管理器,使用"添加"-->"添加类",在类文件名处输入"TextBuilder.ashx.cs"。使用IE测试,输入这个.ashx的地址即可
.ashx 文件用于写web handler的。其实就是带HTML和C#的混合文件。当然你完全可以用.aspx 的文件后缀。使用.ashx 可以让你专注于编程而不用管相关的WEB技术。.ashx必须包含IsReusable. 如下例所示
<% @ webhandler language="C#" class="AverageHandler" %>
using System;
using System.Web;
public class AverageHandler : IHttpHandler
{
public bool IsReusable
{ get { return true; } }
public void ProcessRequest(HttpContext ctx)
{
ctx.Response.Write("hello");
}
}
.ashx比.aspx的好处在与不用多一个html
注意了VS2005中Web应用程序项目模板里的Generic Handler 项,发现它是一个.ashx文件,实际上它是一个HttpHandler。后来查了一下.Net SDK文档,发现Asp.Net1.1也支持.ashx,但是没有给出详细内容。
我们都知道,HttpHandler是一个彻底自定义Http请求的方法,它通过web.config来定义Asp.Net运行时来过滤出要自定义的Http请求,发送到定义在web.config的指定类中。
利用.ashx文件是一个更好的方法,这个文件类似于.aspx文件,可以通过它来调用HttpHandler类,从而免去了普通.aspx页面的控件解析以及页面处理的过程。这个文件特别适合于生成动态图片,生成动态文本等内容。
建立方法如下:
首先打开一个Web项目,然后在任意目录下使用VS2003解决方案资源管理器的“添加”-->“添加新项”,在对话框中选择“文本文件”,然后在文件名处输入“TextBuilder.ashx”。
然后在同目录下,使用解决方案资源管理器,使用“添加”-->“添加类”,在类文件名处输入“TextBuilder.ashx.cs”。可以看出,它的文件命名规律与.aspx文件相同。
然后在.cs文件处输入以下代码(名称空间略):
using System.Web
public sealed class TextBuilder : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ClearContent();
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
context.Response.End();
}
public bool IsReusable
{
get { return true; }
}
}
然后在“TextBuilder.ashx”文件的第一行处输入上面这个类的调用代码:
<%@ WebHandler language="C#" Class="MyNamespace.TextBuilder" codebehind="TextBuilder.ashx.cs" %> 上面的代码需要注意的是:必须在Class项中输入类的完整名称,即包括名称空间及类名称。
最后保存并编译项目。
使用IE测试,输入这个.ashx的地址即可。
大家可以看出Response类有个OutputStream方法,可以向客户端输出二进制数据流,所以在我的项目中,使用这个方法,在一个.ashx中使用DundasChart控件就可以生成非常好的统计图,用它发送二进制数据,方便快捷,而且不需在web.config内输入任何配置代码。
.ashx文件有个缺点,他处理控件的回发事件非常麻烦,比如说如果用它来生成DataGrid的列表也不是不行,但是处理数据的回发,需要一些.aspx页的功能,只有自己手动处理这些功能。所以,一般使用.ashx,用来输出一些不需要回发处理的项目即可。
---------------------------------------------------------------------
什么是HttpHandler
HttpHandler是一个HTTP请求的真正处理中心,也正是在这个HttpHandler容器中,ASP.NET Framework才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。
IHttpHandler是什么
IHttpHandler定义了如果要实现一个HTTP请求的处理所必需实现的一些系统约定。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方法来处理的。
图1:ProcessRequest方法
一个简单的HttpHandler容器
通过实现IHttpHandler接口可以创建自定义HTTP处理程序,该接口只包含两个方法。通过调用IsReusable,IHttpHandlerFactory可以查询处理程序以确定是否可以使用同一实例为多个请求提供服务。ProcessRequest方法将HttpContext实例用作参数,这使它能够访问Request和Response内部对象。在一个HttpHandler容器中如果需要访问Session,必须实现IRequiresSessionState接口,这只是一个标记接口,没有任何方法。
示例1:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.SessionState;
namespace MyHandler
{
///
/// 目的:实现一个简单的自定义HttpHandler容器
/// 作者:文野
/// 联系:stwyhm@cnblogs.com
///
public class MyFirstHandler : IHttpHandler,IRequiresSessionState
{
#region IHttpHandler 成员
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("
Hello HttpHandler
");
context.Session["Test"] = "测试HttpHandler容器中调用Session";
context.Response.Write(context.Session["Test"]);
}
#endregion
}
}
在Web.config中加入如下配置:
<httpHandlers>
<add verb="*" path="*" type="MyHandler.MyFirstHandler, MyHandler"/>
< span>httpHandlers>
IHttpHandler工厂
ASP.NET Framework实际不直接将相关的页面资源HTTP请求定位到一个其内部默认的IHttpHandler容器之上,而定位到了其内部默认的IHttpHandler工厂上。IHttpHandler工厂的作用是对IHttpHandler容器进行调度和管理。
IHttpHandlerFactory接口包含两个方法。GetHandler返回实现IHttpHandler接口的类的实例,ReleaseHandler使工厂可以重用现有的处理程序实例。
示例2:
示例2:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace MyHandler
{
public class MyHandlerFactory : IHttpHandlerFactory
{
#region IHttpHandlerFactory 成员
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
string fname = url.Substring(url.IndexOf('/') + 1);
while (fname.IndexOf('/') != -1)
fname = fname.Substring(fname.IndexOf('/') + 1);
string cname = fname.Substring(0, fname.IndexOf('.'));
string className = "MyHandler." + cname;
object h = null;
try
{
// 采用动态反射机制创建相应的IHttpHandler实现类。
h = Activator.CreateInstance(Type.GetType(className));
}
catch (Exception e)
{
throw new HttpException("工厂不能为类型"+cname+"创建实例。",e);
}
return (IHttpHandler)h;
}
public void ReleaseHandler(IHttpHandler handler)
{
}
#endregion
}
public class Handler1 : IHttpHandler
{
#region IHttpHandler 成员
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("
来自Handler1的信息。
");
}
#endregion
}
public class Handler2 : IHttpHandler
{
#region IHttpHandler 成员
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("
来自Handler2的信息。
");
}
#endregion
}
}