【asp源码栏目提醒】:网学会员为广大网友收集整理了,ASPNet中自定义Http处理及其应用 - 人力资源,希望对大家有所帮助!
精编资料 HttpApplication 定义了所有
ASP.Net应用程序的通用的方法属性和事件.这个类也是在用户在global.asax文件中定义的应用的基类.Modules 处理请求前和响应后的事件... 应用
ASP.Net中自定义Http处理及其应用孙亚民 一、简介 在开发基于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应用程序中系统使用一组相关的类通过一定的顺序来处理客户端的请求RequestASP.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对请求进行具体处理 处理的过程可以用图表示如下 IHttpModule IhttpHandler Factory IHttpHandle HttpContext HttpRequest HttpResponse ???? HttpApplication HttpApplication Factory HttpRuntime HttpApplication Module Handler Factory Handler inetinfo.exe ASPNET_WP.EXE 图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 ProcessRequestHttpContext ctx bool IsReuseable get 接口中ProcessRequest是添加自己的代码进行相应处理的地方。
IsReuseable属性指明该HttpHandler的实现类是否需要缓存。
下面的示例展示了HttpHandler的基本使用 1、建立一个名为MyNameSpace的工程添加一个类名称为MyHandler代码如下 例1 namespace MyNameSpace public class MyHandler : IHttpHandler public void ProcessRequestHttpContext ctx HttpResponse Response Response.WriteThis is my handler public bool IsReusable get return true 2、将上面的代码编译生成MyNameSpace.Dll文件 3、建立一个新的WebApplication项目或打开一个WebApplication项目将文件MyNameSpace.Dll添加到项目的引用中或复制到项目的bin目录下 aspnet_isapi HTTP HttpRuntime Named Pipe 4、修改Web.Config添加如下内容 配置文件中的选项说明 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文件 为了让对后缀名为.foo的文件的请求能够被我们的Handler截获运行我们还需要一些额外的工作。
打开IIS的管理控制台又键单击站点选择“属性”跳出站点的属性对话框。
选择主目录选项。
如图3 图3Web站点属性对话框 选择配置弹出应用程序配置对话框将“.foo”添加到应用程序映射中如图4 图4添加应用程序映射 好了我们现在可以在项目中添加一个.foo文件当向该文件发送请求时浏览器显示 This is my handler 而对其他ASPX文件的访问不受影响。
四、实现Handler Factory 实现HttpHandler功能的另外一个选择是实现一个Handler Factory这是通过实现IHttpHandlerFactory接口来实现的。
IHttpHandlerFactory接口的定义如下 interface IHttpHandlerFactory IHttpHandler GetHandlerHttpContext ctx string requestType string url string pathTranslated void ReleaseHandlerIHttpHandler handler GetHandler方法在请求开始的时候被调用而ReleaseHandler在请求结束所有的Handler都不再需要的时候被调用 使用HttpHandlerFactory的过程一般如下 首先定义实际处理HttpHandler的类这个类会在HandlerFactory中被调用以进行实际的处理 public class BasicHandler : IHttpHandler ... 然后定义自己的HandlerFactory public class BasicHandlerFactory : IHttpHandlerFactory public IHttpHandler GetHandlerHttpContext ctx string requestType string url string pathTranslated return new BasicHandler public void ReleaseHandlerIHttpHandler handler 最后在Web.Config文件中注册这个Factory 五、异步Handler 通过实现IHttpAsyncHandler可以实现对HTTP请求的异步处理。
IHttpAsyncHandler接口继承IHttpHandler也需要实现ProcessRequest 方法和 IsReusable 属性同时需要实现 BeginProcessRequest 和 EndProcessRequest 方法。
BeginProcessRequest 启动异步调用以处理单个的 HTTP 请求而 EndProcessRequest 则在该进程结束时执行清理代码。
IHttpAsyncHandler的实现和注册同IHttpHandler类似读者可以参考MSDN的相关文档。
六、HttpModule的实现 HttpModules实现了类似于ISAPI Filter的功能在开发上通常需要经过以下步骤 1. 编写一个类实现IhttpModule接口 2. 实现Init 方法并且注册需要的方法 3. 实现注册的方法 4. 实现Dispose方法如果需要手工为类做一些清除工作可以添加Dispose方法的实现但这不是必需的通常可以不为Dispose方法添加任何代码。
5. 在Web.config文件中注册您编写的类 下面是一个HttpModules的示例在这个示例中只是简单的注册了HttpApplication 的BeginRequest 和 EndRequest事件并且通过这些事件的实现方法将相关的信息打印出来。
例 1 using System using System.Web namespace MyModule public class MyModule : IHttpModule public void InitHttpApplication application application.BeginRequest new EventHandlerthis.Application_BeginRequest application.EndRequest new EventHandlerthis.Application_EndRequest private void Application_BeginRequestObject source EventArgs e HttpApplication Application HttpApplicationsource HttpResponse ResponseApplication.Context.Response Response.WriteBeginning of Request private void Application_EndRequestObject source EventArgs e HttpApplication application HttpApplicationsource HttpResponse ResponseApplication.Context.Response Response.WriteEnd of Request public void Dispose 程序的开始引用了如下名称空间 using System using System.Web 因为HttpApplication 、HttpContext、HttpResponse等类在System.Web中定义因此System.Web名称空间是必须引用的。
MyModule类实现了IhttpModule接口。
在Init方法中指明了实现BeginRequest 和EndRequest 事件的方法。
在这两个方法中只是简单的分别打印了一些信息。
下面在Web.config文件中注册这个类就可以使用这个HttpModule了注册的方法如下 现在来看一下效果。
编写一个Aspx页面test.aspx内容如下 运行以后的界面如图所示 图1 七、深入研究HttpModule HttpModule通过对HttpApplication对象的一系列事件的处理来对HTTP处理管道施加影响这些事件在HttpModule的Init方法中进行注册包括 BeginRequest AuthenticateRequest AuthorizeRequest ResolveRequestCache AcquireRequestState PreRequestHandlerExecute PostRequestHandlerExecute ReleaseRequestState UpdateRequestCache EndRequest 其中部分事件同Global.asax中的事件相对应对应关系如下 HttpModule Global.asax BeginRequest Application_BeginRequest AuthenticateRequest Application_AuthenticateRequest EndRequest Application_EndRequest 图3 在例1中处理了BeginRequest和EndRequest事件其他事件的处理方式基本上类似。
同HttpHandler对应来看这些事件有些在HttpHandler之前发生有些在HttpHandler处理完后发生。
了解事件发生的顺序非常重要因为服务器端的对象在不同的时间段有着不同的表现。
例子之一是Session的使用。
不是所有的事件中都能对Session进行处理而只能在有限的几个事件中进行处理。
详细的过程可以参考下面的HTTP Request处理生命周期图。
HttpRequest开始 HttpModule HttpModule.AcquireRequestState HttpModule.PreSendRequestContent 建立HttpHandler控制点 HttpHandler.ProcessRequest HttpHandler HttpModule.BeginRequest HttpModule.AuthorizeRequest 将处理的数据返回客户端处理结束 HttpModule.PostRequestHandlerExecute HttpModule.ResolveRequestCache HttpModule.PreRequestHandlerExecute HttpModule.PreSendRequestHeaders HttpModule.EndRequest HttpModule.UpdateRequestCache HttpModule.ReleaseRequestState 进入HttpModule 首次截获HttpRequest 初始化HttpHandler HttpModule继续处理。
HttpHandler已经建立此后Session可用 进入HttpHandler处理HttpRequest 返回HttpModuleHttpHandler结束Session失效 八、使用HttpModule实现权限系统 我们在开发应用系统的时候应用系统的权限控制是非常重要的一个部分。
在
ASP中要实现权限的控制是比较麻烦的事情因为我们必须在每个需要控制权限的
ASP页面中添加权限控制代码从而控制客户对页面的访问。
这样带来的问题除了编写大量重复代码外由于权限控制部分同业务处理部分的模块紧密耦合在一起对权限控制模块的修改往往又会带来大量的修改工作甚至造成大量的Bug。
所以我们现在需要将权限控制和业务处理模块进行解耦使得两个部分可以独立开发和修改而不会互相影响或者将影响减到最低。
在Jsp程序中这个目的可以通过引入一个前端控制器来实现权限过滤关于前端控制器模式可以参见《J2EE核心模式一书》。
在
ASP.Net中我们可以利用HttpModule实现同样的效果。
下面来看一下实现的过程。
首先我们会构建一个权限处理系统可以检测某个用户对某个模块功能是否有访问权限具体的结构我想读者都应该接触过这个部分的编程所以不再赘述其中暴露给客户端调用的权限校验类的定义如下 public class RightChecker public static bool HasRightUser userModule module //进行权限校验 然后我们利用HttpModule编写一个过滤器 using System using System.Web namespace MyModule public class MyModule : IHttpModule public void InitHttpApplication application application. AcquireRequestState new EventHandlerthis.Application_AcquireRequestState private void Application_AcquireRequestState Object source EventArgs e HttpApplication Application HttpApplicationsource User userApplication.Context.Sesseion“User” //获取User string urlApplication.Context.Request.Path //获取客户访问的页面 Module module //根据url得到所在的模块 IfRightChecker.HasRightusermodule Application.Context.Server.Transfer“ErrorPage.aspx” //如果没有权限引导到错误处理的页面 public void Dispose 将这个类按照前面介绍的方法在Web.Config中注册后我们的应用系统就具备权限管理的功能了。
怎么样比原来的方式好很多吧 九、结束语 在.Net中微软把原来具有较高难度的服务器扩展的编程作了很大的简化对于我们开发的确带来了很大的方便值得我们对此技术进行深入的研究。
参考资料 MSDN
上一篇:
程序设计教程
下一篇:
经典感言