ASP.Net中自定义Http处理及应用之HttpHandler篇

ASP.Net中自定义Http处理及应用之HttpHandler篇


           无论做什么方面,基础是最重要的,万层高楼平底起就是这个意思。在编程这方面,基础扎实的遇到复杂的问题也能找到解决办法,而不只是现在coding模式,做了一段时间的编码工作了,现在发现基础是如此的重要,废话不多说,进入今天的主题,下面是我今天看到一个很实用的东西,就是HttpHandler,如果能使用这个类的话就能比较简单的实现一些强大的功能,现在转载过来供大家学习和交流。

    在开发基于Microsoft IIS的应用时,开发者除了可以编写ASP程序外,还可以使用Visual C++等开发工具,开发ISAPI应用,以获取更为强大的功能。可以编写两种ISAPI扩展:一种是ISAPI Server Extention,另一种是ISAPI Filter,但是,ISAPI扩展应用的编写通常对开发者有比较高的要求,开发和部署的难度比较大。 在开发ASP.Net应用时,我们仍然可以编写ISAPI应用,以扩充IIS的功能,但是,ASP.Net为我们提供了另外一种选择——使用HTTP Handler 和HTTP Module。这是通过使用IHttpHandler 和 IHttpModule接口来实现的。HTTP Handler提供了类似于ISAPI Server Extention的功能,而HttpModule实现了类似于ISAPI Filter的功能,并且,比ISAPI,在开发和部署上都要简单的多。 应用HttpHandler和HttpModule,使应用程序可以与IIS Web服务器的低级别请求和响应服务交互。本文首先介绍HttpHandler和HttpModule的概念和基本使用方法,并介绍了一个应用 HttpModule实现权限系统的案例。
HTTP 处理管道的基本模型
要对HttpModule和IHttpHandler进行 研究,必须先对ASP.Net的处理管道有一个了解。 在ASP.Net应用程序中,系统使用一组相关的类,通过一定的顺序来处理客户端的请求(Request),ASP.NET应用程序的处理模式可称之为 HTTP处理管道。HttpModule和IhttpHandler就是这个处理管道上的两个处理环节。 HTTP处理管道中的类在System.Web名称空间中定义,主要有以下类型: · HttpWorkerRequest 抽象类定义了ASP.Net页面处理请求的基本方法; · HttpRuntime 提供了处理应用的一组服务; · HttpContext 保存了处理一次请求的所有相关上下文信息; · HttpApplicationFactory 提供相关目录的应用程序; · HttpApplication 定义了所有ASP.Net应用程序的通用的方法、属性和事件。这个类也是在用户在global.asax文件中定义的应用的基类; · Modules 处理请求前和响应后的事件; · HandlerFactories 提供应用程序中的Handlers; · Handlers 处理请求和响应。 HTTP处理管道的模型如下:
                                      ASP.Net中自定义Http处理及应用之HttpHandler篇_第1张图片
图1:HTTP 处理管道
在Windows 平台上,HTTP Pipline需要IIS的支持。为了运行ASP.NET应用,IIS需要以下两个文件:ASPNET_ISAPI.DLL和ASPNET_WP.EXE · ASPNET_ISAPI.DLL是一个ISAPI Extention他将发向IIS的请转交ASPNET_WP.EXE处理 · ASPNET_WP.EXE使用HttpRuntime对请求进行具体处理 处理的过程可以用图表示如下:
                                      
图2:IIS上的HTTP处理管道

HttpHandler的实现
HttpHandler 实现了类似于ISAPI Extention的功能,他处理请求(Request)的信息和发送响应(Response)。HttpHandler功能的实现通过实现 IHttpHandler接口来达到。实际上,我们在编写ASP.Net页面时,ASP.Net页面所继承的基类—— System.Web.UI.Page——也实现了HttpHandler接口,也是一个HttpHandler,看一下它的定义就知道了(C#):
public class Page : TemplateControl, IhttpHandler


接口IHttpHandler的定义如下:
interface IHttpHandler
{
void ProcessRequest(HttpContext ctx);
bool IsReuseable { get; }
}


接 口中ProcessRequest是添加自己的代码,进行相应处理的地方。IsReuseable属性指明该HttpHandler的实现类是否需要缓 存。 下面的示例展示了HttpHandler的基本使用: 1、建立一个名为MyNameSpace的工程,添加一个类,名称为MyHandler,代码如下:
例1:
namespace MyNameSpace
{
public class MyHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
HttpResponse Response
Response.Write("This is my handler");}
public bool IsReusable
{
get { return true; }
}
}
}


2、 将上面的代码编译,生成MyNameSpace.Dll文件; 3、建立一个新的WebApplication项目,或打开一个WebApplication项目,将文件MyNameSpace.Dll添加到项目的引 用中,或复制到项目的bin目录下; 4、修改Web.Config,添加如下内容:
<configuration>
<system.web>
<httpHndlers>
<add verb="*" path="*.aspx"
type=" MyNameSpace.MyHandr, MyNameSpace" />
</httpHndlers>
</system.web>
</configuration>


配 置文件中的选项说明:
· verb可以是"GET"或"POST",表示对GET或POST的请求进行处理。"*"表示对所有请求进行处理。
· Path指明对相应的文件进行处理,"*.aspx"表示对发给所有ASPX页面的请求进行处理。可以指明路径,如"/test/*.aspx",表明只 对test目录下的ASPX文件进行处理。
· Type属性中,逗号前的字符串指明HttpHandler的实现类的类名,后面的字符串指明Dll文件的名称。 现在,请求项目中的任何ASPX页面,页面上显示的始终只有如下一行字:
This is my handler



因为,我们自定义的Handler截获了所有发向ASPX页面的请求,并且用自己的的方法来处理这些请求了。 为了使我们的ASPX页面能够顺利运行,我们需要修改Web.Config文件:
<configuration>
<system.web>
<httpHndlers>
<add verb="*" path="*.foo"
type=" MyNameSpace.MyHandr,hander" />
</httpHndlers>
</system.web>
</configuration>



为了让对后缀名为.foo的文件的请求能够被我们的Handler截获运行,我们还需要一些额外的工作。打开IIS的管理控制台,又键单击站点,选择"属性",跳出站点的属性对话框。选择主目录选项。如图3:

ASP.Net中自定义Http处理及应用之HttpHandler篇_第2张图片

图3:Web站点属性对话框
选择配置,弹出应用程序配置对话框,将".foo"添加到应用程序映射中,如图4:
ASP.Net中自定义Http处理及应用之HttpHandler篇_第3张图片
图4:添加应用程序映射
好了,我们现在可以在项目中添加一个.foo文件,当向该文件发送请求时,浏览器显示:
This is my handler
而对其他ASPX文件的访问不受影响。


2、实现Handler Factory
实现HttpHandler功能的另外一个选择是实现一个Handler Factory,这是通过实现IHttpHandlerFactory接口来实现的。 IHttpHandlerFactory接口的定义如下:
interface IHttpHandlerFactory
{
IHttpHandler GetHandler(HttpContext ctx,
string requestType,
string url,
string pathTranslated);
void ReleaseHandler(IHttpHandler handler);
}

GetHandler方法在请求开始的时候被调用,而ReleaseHandler在请求结束,所有的Handler都不再需要的时候被调用。 使用HttpHandlerFactory的过程一般如下:
1)首先定义实际处理HttpHandler的类,这个类会在HandlerFactory中被调用以进行实际的处理:
public class BasicHandler : IHttpHandler { ... }

2)然后,定义自己的HandlerFactory:
public class BasicHandlerFactory : IHttpHandlerFactory
{
public IHttpHandler GetHandler(HttpContext ctx,
string requestType,
string url,
string pathTranslated)
{
return new BasicHandler();
}
public void ReleaseHandler(IHttpHandler handler) {}
}

3)最后,在Web.Config文件中注册这个Factory:
<configuration>
<system.web>
<httpHandlers>
<add verb="POST" path="*.foo"
type="MyNamespace.BasicHandlerFactory, MyAssembly" />
</httpHandlers>
</system.web>
</configuration>

异步Handler
通 过实现IHttpAsyncHandler可以实现对HTTP请求的异步处理。IHttpAsyncHandler接口继承IHttpHandler,也 需要实现ProcessRequest 方法和 IsReusable 属性,同时,需要实现 BeginProcessRequest 和 EndProcessRequest 方法。BeginProcessRequest 启动异步调用以处理单个的 HTTP 请求,而 EndProcessRequest 则在该进程结束时执行清理代码。 IHttpAsyncHandler的实现和注册同IHttpHandler类似,读者可以参考MSDN的相关文档。 现在,大家是否对HTTP Handler的概念和应用有了一定的了解?在下一篇文章中,我们将主要介绍HTTP Module的的应用,并给出使用HttpModule实现权限系统的实例。

==============================================================================

很多时候,我们新建一个xxx.aspx页和xxx.aspx.cs文件,不过是为了实现一个很简单的功能,如:输出xmlDom,注销并跳转,并 没有什么html的输出,很是麻烦,需要新建一个页,删除多余的html,并在page_load里面写处理代码。而使用HttpHandler就不需要 这么麻烦了。

可以用任何符合公共语言规范 (CLS) 的语言编写自定义 HTTP 处理程序来处理特定的、预定义类型的 HTTP 请求。响应这些特定请求的是在 HttpHandler 类中定义的可执行代码,而不是常规的 ASP 或 ASP.NET Web 页。HTTP 处理程序向您提供一种方法,使您可以与 IIS Web 服务器的低级别的请求和响应服务交互,同时提供极其类似于 ISAPI 扩展但编程模型较为简单的功能。

例如我现在需要实现一个注销并跳转的Logout.aspx页面,下面的示例主要实现了响应客户端对名为 logout.aspx 的页的请求,实现注销并跳转。对 logout.aspx 的所有请求均由包含在程序集 WebUC.dll 中的命名空间 WebUC.HttpHandler 中的 LogoutHttpHandler 提供服务。

修改web.config,在<system.web></system.web>中增加如下脚本:
<httpHandlers>
<add verb="GET" path="Logout.aspx" type="WebUC.HttpHandler.LogoutHttpHandler, WebUC" />
</httpHandlers>
其中WebUC.HttpHandler.LogoutHttpHandler是我要实现Logout.aspx功能的类,WebUC是我web项目的dll。(具体介绍可以参阅msdn)

下面是LogoutHttpHandler的代码,继承接口,重写方法和属性。

using System;
using System.Web;
using System.Web.Caching;
using System.Web.Security;

namespace WebUC.HttpHandler
{

public class LogoutHttpHandler : IHttpHandler
{
/// <summary>
/// 通过实现 IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
/// </summary>
/// <param name="context">HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。 </param>
public void ProcessRequest (HttpContext context)
{
FormsAuthentication.SignOut();
context.Response.Redirect("Login.aspx",true);
}

/// <summary>
/// 获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。
/// </summary>
public bool IsReusable
{
get
{
return false;
}
}
}

}
}

编译后,我就可以直接使用http://***/logout.aspx 来实现注销了,而实际上,我的web目录下并没有logout.aspx这个文件,同样,这个技巧可以用在很多方面,例如防止盗链,下载统计等。

本文转载自:http://webzixue.iteye.com/blog/1227489


你可能感兴趣的:(ASP.Net中自定义Http处理及应用之HttpHandler篇)