zoukankan      html  css  js  c++  java
  • asp.net的HTTP请求处理过程

    1、asp.net的HTTP请求处理过程

    说明:
    (1)、客户端浏览器向服务器发出一个http请求,此请求会被inetinfo.exe进程截获,然后转交给aspnet_isapi.dll进程,接着它又通过Http Pipeline的管道,传送给aspnet_wp.exe这个进程,接下来就到了.net framework的HttpRunTime处理中心,处理完毕后就发送给用户浏览器。
    (2)、当一个http请求被送入到HttpRuntime之后,这个Http请求会继续被送入到一个被称之为HttpApplication Factory的一个容器当中,而这个容器会给出一个HttpApplication实例来处理传递进来的http请求,而后这个Http请求会依次进入到如下几个容器中:HttpModule --> HttpHandler Factory --> HttpHandler。当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成了,客户端也就得到相应的东东了。
    (3)完整的http请求在asp.net framework中的处理流程:
    HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

    也就是说一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的HTTP请求处理工作。
    而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个HTTP请求之后,会将控制权交还给HttpModule,HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。

    (4)如果想在中途截获一个httpRequest并做些自己的处理,就应该在HttpRuntime运行时内部来做到这一点,确切的说是在HttpModule这个容器中来实现。

    2、HttpModule工作原理


         负责监听HttpRequest,同时对HttpRequest增添或者过滤掉一部分内容。也就是说,当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。
    HttpModule实现了接口IHttpModule,我们可以自定义实现该接口的类,从而取代HttpModule。 
    asp.net默认的HttpModule如下:

            1.System.Web.SessionState.SessionStateModule;
    
    
    
            2.System.Web.Security.WindowsAuthenticationModule;
    
    
    
            3.System.Web.Security.FormsAuthenticationModule;
    
    
    
            4.System.Web.Security.PassportAuthenticationModule;
    
    
    
            5.System.Web.Security.UrlAuthorizationModule;
    
    
    
            6.System.Web.Security.FileAuthorizationModule;

    3、编写自己的HttpModule

    要实现HttpModule,必须实现接口IHttpModule。下面是IHttpModule接口分析:

    using System;
    namespace System.Web
    {
       public interface IHttpModule
        {
    
    
    
            //   销毁不再被HttpModule使用的资源
            void Dispose();
    
    
            // 初始化一个Module,为捕获HttpRequest做准备
            void Init(HttpApplication context);
    
    
    
        }
    }
    下面是自己的HttpModule:
    using System;
    using System.Web;
    namespace ClassLibrary1
    {
        public class MyHttpModule : IHttpModule
        {
            public void Dispose() { }
            public void Init(HttpApplication context)
            {
                context.BeginRequest += new EventHandler(Application_BeginRequest);
                context.EndRequest += new EventHandler(Application_EndRequest);
            }
            public void Application_BeginRequest(object sender, EventArgs e)
            {
                HttpApplication application = sender as HttpApplication;
                HttpContext context = application.Context;
                HttpResponse response = context.Response;
                response.Write("这是来自自定义HttpModule中有BeginRequest");
            }
    
    
            public void Application_EndRequest(object sender, EventArgs e)
            {
                HttpApplication application = sender as HttpApplication;
                HttpContext context = application.Context;
                HttpResponse response = context.Response;
                response.Write("这是来自自定义HttpModule中有EndRequest");
    
    
    
            }
    
    
        }
    
    
    
    }
    
    web.config:
    myHttpModule" type="ClassLibrary1.MyHttpModule,ClassLibrary1"/>

    default.aspx.cs
    using System;
    
    
    
    
    
    
    
    using System.Collections.Generic;
    
    
    
    
    
    
    
    using System.Linq;
    
    
    
    
    
    
    
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    public partial class _Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
        {
    
            Response.Write("来自Default.aspx页面");
        }
    
    
    }
    
    
    

    4、HttpModule内部事件机制和生命周期

    HttpModule对HttpApplication实例进行处理,而HttpApplication有很多事件(对应不同的生命期),这样就衍生出HttpModule内部事件机制和生命周期。 
    (1)、HttpModule的事件

       
    BeginRequest 指示请求处理开始
    AuthenticateRequest 封装请求身份验证过程
    AuthorizeRequest 封装检查是否能利用以前缓存的输出页面处理请求的过程
    ResolveRequestCache 从缓存中得到相应时候触发
    AcquireRequestState 加载初始化Session时候触发
    PreRequestHandlerExecute 在Http请求进入HttpHandler之前触发
    PostRequestHandlerExecute 在Http请求进入HttpHandler之后触发
    ReleaseRequestState 存储Session状态时候触发
    UpdateRequestCache 更新缓存信息时触发
    EndRequest 在Http请求处理完成的时候触发
    PreSendRequestHenaders 在向客户端发送Header之前触发
    PreSendRequestConternt 在向客户端发送内容之前触发

    说明: 
    a、BenginRequest和EndRequest分别是HttpModule容器最开始的和最后的事件; 
    b、EndRequest之后还会触发PreSendRequestHeaders事件和PreSendRequestContent事件,这不是在HttpModule外的两个事件,表示HttpModule结束,即将开始向Client发送数据

    2)、验证HttpModule生命周期 
    与HttpHandler的交互:
    说明: 
    a、HttpModule容器会将HttpRequest传递到HttpHandler容器,这个时间点是ResolveRequestCache事件 
    b、HttpModule容器会建立HttpHandler实例作为入口——Session从此生效 
    c、触发AcquireRequestState事件以及PreRequestHandlerExecute事件 
    d、HttpModule容器便将对HttpRequest的控制权转让给HttpHandler容器 
    e、HttpHandler容器处理HttpRequest——使用自身的ProcessRequest方法,将对其控制权又还给HttpModule容器——之后Session失效。
    验证生命周期代码:
    using System;
    
    
    
    using System.Collections.Generic;
    
    
    
    using System.Text;
    
    
    
    using System.Web;
    
    
    
    
    
    
    
    namespace MyHttpModule
    
    
    
    {
    
    
    
        public class ValidaterHttpModuleEvents : IHttpModule
    
    
    
        {
    
    
    
    
    
    
    
            public void Dispose()
    
    
    
            { }
    
    
    
    
    
    
    
            /// 
    
    
    
            /// 验证HttpModule事件机制
    
    
    
            /// 
    
    
    
            /// 
    
    
    
            public void Init(HttpApplication application)
    
    
    
            {
    
    
    
                application.BeginRequest += new EventHandler(application_BeginRequest);
    
    
    
                application.EndRequest += new EventHandler(application_EndRequest);
    
    
    
                application.AcquireRequestState += new EventHandler(application_AcquireRequestState);
    
    
    
                application.AuthenticateRequest += new EventHandler(application_AuthenticateRequest);
    
    
    
                application.AuthorizeRequest += new EventHandler(application_AuthorizeRequest);
    
    
    
                application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);
    
    
    
                application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);
    
    
    
                application.ReleaseRequestState += new EventHandler(application_ReleaseRequestState);
    
    
    
                application.ResolveRequestCache += new EventHandler(application_ResolveRequestCache);
    
    
    
                application.PreSendRequestHeaders += new EventHandler(application_PreSendRequestHeaders);
    
    
    
                application.PreSendRequestContent += new EventHandler(application_PreSendRequestContent);
    
    
    
            }
    
    
    
    
    
    
    
            private void application_BeginRequest(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_BeginRequest
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_EndRequest(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_EndRequest
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_PreRequestHandlerExecute(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_PreRequestHandlerExecute
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_PostRequestHandlerExecute(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_PostRequestHandlerExecute
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_ReleaseRequestState(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_ReleaseRequestState
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_AcquireRequestState(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_AcquireRequestState
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_PreSendRequestContent(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_PreSendRequestContent
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_PreSendRequestHeaders(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_PreSendRequestHeaders
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_ResolveRequestCache(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_ResolveRequestCache
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_AuthorizeRequest(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = (HttpApplication)sender;
    
    
    
                application.Context.Response.Write("application_AuthorizeRequest
    ");
    
    
            }
    
    
    
    
    
    
    
            private void application_AuthenticateRequest(object sender, EventArgs e)
            {
                HttpApplication application = (HttpApplication)sender;
    
                application.Context.Response.Write("application_AuthenticateRequest");
    
    
            }
    
    
    
        }
    
    
    
    }
    
    
    
    HttpModule1" type="MyHttpModule.HttpModule1,MyHttpModule"/>
    
    
    
    HttpModule2" type="MyHttpModule.HttpModule2,MyHttpModule"/>
    
    
    
    

    HttpModule1和HttpModule2模仿ValidaterHttpModuleEvents编写(除了类名改变外,事件和方法不变),不贴代码了。

    从运行结果可以看到,在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。

    (3)、利用HttpModule实现终止此次HttpRequest请求

    在BeginRequest事件中,使用HttpApplication.CompleteRequest()方法可以实现当满足一定条件时终止此次HttpRequest请求 

    using System;
    
    
    
    using System.Web;
    
    
    
    
    
    
    
    namespace ClassLibrary1
    
    
    
    {
    
    
    
        public class MyHttpModule : IHttpModule
    
    
    
        {
    
    
    
            public void Dispose() { }
    
    
    
    
    
    
    
            public void Init(HttpApplication context)
    
    
    
            {
    
    
    
                context.BeginRequest += new EventHandler(Application_BeginRequest);
    
    
    
            }
    
    
    
    
    
    
    
            public void Application_BeginRequest(object sender, EventArgs e)
    
    
    
            {
    
    
    
                HttpApplication application = sender as HttpApplication;
    
    
    
                application.CompleteRequest();
    
    
    
                application.Context.Response.Write("请求被终止");
    
    
    
            }
    
    
    
        }
    
    
    }

    说明: 
    a、对于一个HttpModule,在BeginRquest中终止,但是仍然会调用EndRequest事件,以及PreSendRequestHeaders事件和PreSendRequestContent事件。也可以说是直接跳转到EndRequest事件,而不会调用这期间的事件 
    b、如果有两个HttpModule,在第一个HttpModule的BeginRequest中终止,仅仅不会调用第二个HttpModule的BeginRequest,但仍然会调用两个EndRequest事件,以及PreSendRequestHeaders事件和PreSendRequestContent事件。


  • 相关阅读:
    LA 2038 Strategic game(最小点覆盖,树形dp,二分匹配)
    UVA 10564 Paths through the Hourglass(背包)
    Codeforces Round #323 (Div. 2) D 582B Once Again...(快速幂)
    UVALive 3530 Martian Mining(贪心,dp)
    UVALive 4727 Jump(约瑟夫环,递推)
    UVALive 4731 Cellular Network(贪心,dp)
    UVA Mega Man's Mission(状压dp)
    Aizu 2456 Usoperanto (贪心)
    UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
    Aizu 2304 Reverse Roads(无向流)
  • 原文地址:https://www.cnblogs.com/taomylife/p/8644420.html
Copyright © 2011-2022 走看看