taotao1130

身体,革命的本钱!努力学习ing!

导航

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

Posted on 2005-09-23 12:25  litao  阅读(270)  评论(0编辑  收藏  举报

ASP.Net 中自定义Http 处理及应用之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 处理管道的模型如下:

1HTTP 处理管道

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 对请求进行具体处理  处理的过程可以用图表示如下:

 

2IIS 上的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 


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

3Web 站点属性对话框

选择配置,弹出应用程序配置对话框,将".foo"添加到应用程序映射中,如图4


                                                   图4:添加应用程序映射

好了,我们现在可以在项目中添加一个.foo文件,当向该文件发送请求时,浏览器显示: 

This is my handler


而对其他ASPX 文件的访问不受影响。 

实现Handler Factory

实现HttpHandler 功能的另外一个选择是实现一个Handler Factory,这是通过实现IHttpHandlerFactor y 接口来实现的。 


IHttpHandlerFactory
接口的定义如下: 

interface IHttpHandlerFactory 

IHttpHandler GetHandler(HttpContext ctx,    
string requestType, string url,
string pathTranslated); 

void ReleaseHandler(IHttpHandler handler); 
}


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

public class BasicHandler : IHttpHandler {  }

 

GetHandler 方法在请求开始的时候被调用,而在请求结束,所有的都不再需要的时候被调用。使用的过程一般如下:首先定义实际处理的类,这个类会在中被调用以进行实际的处理:

然后,定义自己的HandlerFactory 

public class BasicHandlerFactory : IHttpHandlerFactory 

public IHttpHandler GetHandler(HttpContext ctx, string requestType, string url, string pathTranslated) 

return new BasicHandler(); 

public void ReleaseHandler(IHttpHandler handler) {} 
}



最后,在Web.Config 文件中注册这个Factory 

<configuration> 
<system.web> 
<httpHandlers> 
<add verb="POST" path="*.foo" type="MyNamespace.BasicHandlerFactory, MyAssembly" /> 
</httpHandlers> 
</system.web> 
</configuration>




异步Handler

通过实现IHttpAsyncHandler 可以实现对HTTP 请求的异步处理。IHttpAsyncHandler 接口继承IHttpHandle r,也需要实现ProcessRequest 方法和IsReusable 属性,同时,需要实现BeginProcessRequest EndProcessRequest 方法。BeginProcessRequest 启动异步调用以处理单个的HTTP 请求,而 EndProcessRequest 则在该进程结束时执行清理代码。

IHttpAsyncHandler 的实现和注册同IHttpHandler 类似,读者可以参考MSDN 的相关文档。 

现在,大家是否对HTTP Handler 的概念和应用有了一定的了解?在下一篇文章中,我们将主要介绍HTTP Module 的的应用,并给出使用HttpModule 实现权限系统的实例。 

作者介绍:孙亚民,毕业于南京大学,苏州某软件公司技术总监,熟悉.NetJ2EE 架构,以及UML Rational Rose,您可以到作者专栏与他交流。