zoukankan      html  css  js  c++  java
  • ASP.Net中自定义Http处理及应用之HttpHandler篇 1

    ASP.Net中自定义Http处理及应用之HttpModule篇
    作者:孙亚民 发文时间:2002.12.26

    HttpHandler实现了类似于ISAPI Extention的功能,他处理请求(Request)的信息和发送响应(Response)。HttpHandler功能的实现通过实现IHttpHandler接口来达到。而HttpModule实现了类似于ISAPI Filter的功能。 

    HttpModule的实现


    HttpModules实现了类似于ISAPI Filter的功能,在开发上,通常需要经过以下步骤: 

    1.编写一个类,实现IhttpModule接口 

    2.实现Init 方法,并且注册需要的方法 

    3.实现注册的方法 

    4.实现Dispose方法,如果需要手工为类做一些清除工作,可以添加Dispose方法的实现,但这不是必需的,通常可以不为Dispose方法添加任何代码。 

    5.在Web.config文件中,注册您编写的类 

    下面是一个HttpModules的示例,在这个示例中,只是简单的注册了HttpApplication 的BeginRequest 和 EndRequest事件,并且通过这些事件的实现方法,将相关的信息打印出来。 

    <ccid_nobr>
    <ccid_code>例1:
    using System;
    using System.Web; 
    namespace MyModule
    {
    	public class MyModule : IHttpModule 
    	{
    		public void Init(HttpApplication application) 
    		{ 
    			application.BeginRequest += (new 
    EventHandler(this.Application_BeginRequest));
    			application.EndRequest += (new 
    EventHandler(this.Application_EndRequest));
    		}
        		private void Application_BeginRequest(Object source, EventArgs e) 
    		{
    			HttpApplication Application = (HttpApplication)source;
               	HttpResponse Response=Application.Context.Response;
    			Response.Write("<h1>Beginning of Request</h1><hr>");
    		}
        		private void Application_EndRequest(Object source, EventArgs e) 
    		{
    			HttpApplication application = (HttpApplication)source;
    			HttpResponse Response=Application.Context.Response;
    			Response.Write("<h1>End of Request</h1><hr>");
    		}        
    		public void Dispose() 
    		{
    		}
    	}
    }


    程序的开始引用了如下名称空间: 

    <ccid_nobr>
    <ccid_code>using System;
    using System.Web;


    因为HttpApplication、HttpContext、HttpResponse等类在System.Web中定义,因此,System.Web名称空间是必须引用的。 

    MyModule类实现了IhttpModule接口。在Init方法中,指明了实现BeginRequest 和EndRequest 事件的方法。在这两个方法中,只是简单的分别打印了一些信息。 

    下面,在Web.config文件中注册这个类,就可以使用这个HttpModule了,注册的方法如下: 

    <ccid_nobr>
    <ccid_code><configuration>
        <system.web>
            <httpModules>
                <add name=" MyModule " type=" MyModule, MyModule" /> 
            </httpModules>
        </system.web>
    </configuration>


    现在来看一下效果。编写一个Aspx页面test.aspx,内容如下: 

    <ccid_nobr>
    <ccid_code><%
    Response.Write("<h1>This is the Page</h1><hr>");
    %>


    运行以后的界面如图所示: 



    深入研究HttpModule


    HttpModule通过对HttpApplication对象的一系列事件的处理来对HTTP处理管道施加影响,这些事件在HttpModule的Init方法中进行注册,包括: 

    <ccid_nobr>
    <ccid_code>BeginRequest
    AuthenticateRequest
    AuthorizeRequest
    ResolveRequestCache
    AcquireRequestState
    PreRequestHandlerExecute
    PostRequestHandlerExecute
    ReleaseRequestState
    UpdateRequestCache
    EndRequest


    其中部分事件同Global.asax中的事件相对应,对应关系如下: 

    <ccid_nobr>
    HttpModule Global.asax
    BeginRequest Application_BeginRequest
    AuthenticateRequest Application_AuthenticateRequest
    EndRequest Application_EndRequest


    在例1中,处理了BeginRequest和EndRequest事件,其他事件的处理方式基本上类似。 

    同HttpHandler对应来看,这些事件,有些在HttpHandler之前发生,有些在HttpHandler处理完后发生。了解事件发生的顺序非常重要,因为,服务器端的对象在不同的时间段有着不同的表现。例子之一是Session的使用。不是所有的事件中都能对Session进行处理,而只能在有限的几个事件中进行处理。详细的过程可以参考下面的HTTP Request处理生命周期图。 



    使用HttpModule实现权限系统


    我们在开发应用系统的时候,应用系统的权限控制是非常重要的一个部分。在ASP中,要实现权限的控制是比较麻烦的事情,因为我们必须在每个需要控制权限的ASP页面中添加权限控制代码,从而控制客户对页面的访问。这样带来的问题,除了编写大量重复代码外,由于权限控制部分同业务处理部分的模块紧密耦合在一起,对权限控制模块的修改,往往又会带来大量的修改工作,甚至造成大量的Bug。 

    所以,我们现在需要将权限控制和业务处理模块进行解耦,使得两个部分可以独立开发和修改,而不会互相影响,或者,将影响减到最低。在Jsp程序中,这个目的可以通过引入一个前端控制器来实现权限过滤(关于前端控制器模式,可以参见《J2EE核心模式一书》)。在ASP.Net中,我们可以利用HttpModule实现同样的效果。下面来看一下实现的过程。 

    首先,我们会构建一个权限处理系统,可以检测某个用户对某个模块功能是否有访问权限(具体的结构,我想,读者都应该接触过这个部分的编程,所以不再赘述),其中,暴露给客户端调用的权限校验类的定义如下: 

    <ccid_nobr>
    <ccid_code>public class RightChecker
    {
    	public static bool HasRight(User user,Module module)
    	{
    		//进行权限校验,
    }
    }


    然后,我们利用HttpModule编写一个过滤器: 

    <ccid_nobr>
    <ccid_code>using System;
    using System.Web; 
    namespace MyModule
    {
    	public class MyModule : IHttpModule 
    	{
    		public void Init(HttpApplication application) 
    		{ 
    	application. AcquireRequestState += (new 
    EventHandler(this.Application_AcquireRequestState));
    		}
    		private void Application_AcquireRequestState (Object source, 
    EventArgs e) 
    		{
    			HttpApplication Application = (HttpApplication)source;
    			User user=Application.Context.Sesseion["User"]  //获取User
    			string url=Application.Context.Request.Path; 
    //获取客户访问的页面
    			Module module= //根据url得到所在的模块
    			If(!RightChecker.HasRight(user,module))
    Application.Context.Server.Transfer("ErrorPage.aspx"); 
    //如果没有权限,引导到错误处理的页面
    		}
    		public void Dispose() 
    		{
    		}
    	}
    }


    将这个类按照前面介绍的方法,在Web.Config中注册后,我们的应用系统就具备权限管理的功能了。怎么样,比原来的方式好很多吧? 

    结束语


    在.Net中,微软把原来具有较高难度的服务器扩展的编程作了很大的简化,对于我们开发的确带来了很大的方便,值得我们对此技术进行深入的研究。 

    作者介绍:孙亚民,毕业于南京大学,苏州某软件公司技术总监,熟悉.Net和J2EE架构,以及UML和Rational Rose,您可以到作者专栏与他交流。 
  • 相关阅读:
    Add Two Numbers
    Reverse Linked List II
    Reverse Linked List
    Remove Duplicates from Sorted List
    Remove Duplicates from Sorted List II
    Partition List
    Intersection of Two Linked Lists
    4Sum
    3Sum
    2Sum
  • 原文地址:https://www.cnblogs.com/akak123/p/2497128.html
Copyright © 2011-2022 走看看