在开发基于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处理管道的模型如下:
图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:
图3:web站点属性对话框
选择配置,弹出应用程序配置对话框,将".foo"添加到应用程序映射中,如图4:
图4:添加应用程序映射
好了,我们现在可以在项目中添加一个.foo文件,当向该文件发送请求时,浏览器显示:
this is my handler
而对其他aspx文件的访问不受影响。
实现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的过程一般如下: 首先定义实际处理httphandler的类,这个类会在handlerfactory中被调用以进行实际的处理:
public class basichandler : ihttphandler { ... }
然后,定义自己的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接口继承ihttphandler,也需要实现processrequest 方法和 isreusable 属性,同时,需要实现 beginprocessrequest 和 endprocessrequest 方法。beginprocessrequest 启动异步调用以处理单个的 http 请求,而 endprocessrequest 则在该进程结束时执行清理代码。 ihttpasynchandler的实现和注册同ihttphandler类似,读者可以参考msdn的相关文档。 现在,大家是否对http handler的概念和应用有了一定的了解?在下一篇文章中,我们将主要介绍http module的的应用,并给出使用httpmodule实现权限系统的实例。
新闻热点
疑难解答