天天看点

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

在开发基于microsoftiis的应用时,开发者除了可以编写asp程序外,还可以使用visualc++等开发工具,开发isapi应用,以获取更为强大的功能。可以编写两种isapi扩展:一种是isapiserverextention,另一种是isapifilter,但是,isapi扩展应用的编写通常对开发者有比较高的要求,开发和部署的难度比较大。在开发asp.net应用时,我们仍然可以编写isapi应用,以扩充iis的功能,但是,asp.net为我们提供了另外一种选择——使用httphandler和httpmodule。这是通过使用ihttphandler和ihttpmodule接口来实现的。httphandler提供了类似于isapiserverextention的功能,而httpmodule实现了类似于isapifilter的功能,并且,比isapi,在开发和部署上都要简单的多。应用httphandler和httpmodule,使应用程序可以与iisweb服务器的低级别请求和响应服务交互。本文首先介绍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:http处理管道

在windows平台上,httppipline需要iis的支持。为了运行asp.net应用,iis需要以下两个文件:aspnet_isapi.dll和aspnet_wp.exe·aspnet_isapi.dll是一个isapiextention他将发向iis的请转交aspnet_wp.exe处理·aspnet_wp.exe使用httpruntime对请求进行具体处理处理的过程可以用图表示如下:

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

图2:iis上的http处理管道

httphandler的实现

httphandler实现了类似于isapiextention的功能,他处理请求(request)的信息和发送响应(response)。httphandler功能的实现通过实现ihttphandler接口来达到。实际上,我们在编写asp.net页面时,asp.net页面所继承的基类——system.web.ui.page——也实现了httphandler接口,也是一个httphandler,看一下它的定义就知道了(c#):

publicclasspage:templatecontrol,ihttphandler

接口ihttphandler的定义如下:

interfaceihttphandler

{

voidprocessrequest(httpcontextctx);

boolisreuseable{get;}

}

接口中processrequest是添加自己的代码,进行相应处理的地方。isreuseable属性指明该httphandler的实现类是否需要缓存。下面的示例展示了httphandler的基本使用:1、建立一个名为mynamespace的工程,添加一个类,名称为myhandler,代码如下:

例1:

namespacemynamespace

publicclassmyhandler:ihttphandler

publicvoidprocessrequest(httpcontextctx)

httpresponseresponse

response.write("thisismyhandler");}

publicboolisreusable

get{returntrue;}

2、将上面的代码编译,生成mynamespace.dll文件;3、建立一个新的webapplication项目,或打开一个webapplication项目,将文件mynamespace.dll添加到项目的引用中,或复制到项目的bin目录下;4、修改web.config,添加如下内容:

<configuration>

<system.web>

<httphndlers>

<addverb="*"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页面,页面上显示的始终只有如下一行字:

thisismyhandler

因为,我们自定义的handler截获了所有发向aspx页面的请求,并且用自己的的方法来处理这些请求了。为了使我们的aspx页面能够顺利运行,我们需要修改web.config文件:

<addverb="*"path="*.foo"

type="mynamespace.myhandr,hander"/>

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

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

图3:web站点属性对话框

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

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

图4:添加应用程序映射

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

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

实现handlerfactory

实现httphandler功能的另外一个选择是实现一个handlerfactory,这是通过实现ihttphandlerfactory接口来实现的。ihttphandlerfactory接口的定义如下:

interfaceihttphandlerfactory

ihttphandlergethandler(httpcontextctx,

stringrequesttype,

stringurl,

stringpathtranslated);

voidreleasehandler(ihttphandlerhandler);

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

publicclassbasichandler:ihttphandler{...}

然后,定义自己的handlerfactory:

publicclassbasichandlerfactory:ihttphandlerfactory

publicihttphandlergethandler(httpcontextctx,

stringpathtranslated)

returnnewbasichandler();

publicvoidreleasehandler(ihttphandlerhandler){}

最后,在web.config文件中注册这个factory:

<httphandlers>

<addverb="post"path="*.foo"

type="mynamespace.basichandlerfactory,myassembly"/>

</httphandlers>

异步handler

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