• HttpModule工作原理 dodo


    当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。

    示例1

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Web;

    namespace MyHttpModule

    {

         ///<summary>

         ///说明:用来实现自己的HttpModule类。

         ///作者:文野

         ///联系:stwyhm@cnblogs.com

         ///</summary>

         public class MyFirstHttpModule : IHttpModule

         {

             private void Application_BeginRequest(object sender, EventArgs e)

             {

                  HttpApplication application = (HttpApplication)sender;

                  HttpContext context = application.Context;

                  HttpRequest request = application.Request;

                  HttpResponse response = application.Response;

                  response.Write("我来自自定义HttpModule中的BeginRequest<br />");
             }

             private void Application_EndRequest(object sender, EventArgs e)

             {

                  HttpApplication application = (HttpApplication)sender;

                  HttpContext context = application.Context;

                  HttpRequest request = application.Request;

                  HttpResponse response = application.Response;

                  response.Write("我来自自定义HttpModule中的EndRequest<br />");

             }

             #region IHttpModule 成员

             public void Dispose()

             {}

             public void Init(HttpApplication application)

             {

                  application.BeginRequest += new EventHandler(Application_BeginRequest);

                  application.EndRequest += new EventHandler(Application_EndRequest);

             }

             #endregion

         }

    }

    Web.config进行如下配置

    <addname="MyFirstHttpModule"type="MyHttpModule.MyFirstHttpModule,MyHttpModule"/>


     

    一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的HTTP请求处理工作。

    而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个HTTP请求之后,会将控制权交还给HttpModuleHttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。


    1HttpModule生命周期示意图

    示例2:验证HttpModule生命周期

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Web;

    namespace MyHttpModule

    {

        public class ValidaterHttpModule : IHttpModule

        {

            #region IHttpModule 成员

            public void Dispose()

            {}

            public void Init(HttpApplication application)

            {

                application.BeginRequest += new EventHandler(application_BeginRequest);

                application.EndRequest += new EventHandler(application_EndRequest);
             application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);

                application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);

                application.ReleaseRequestState += new EventHandler(application_ReleaseRequestState);

                application.AcquireRequestState += new EventHandler(application_AcquireRequestState);

                application.AuthenticateRequest += new EventHandler(application_AuthenticateRequest);

                application.AuthorizeRequest += new EventHandler(application_AuthorizeRequest);

                application.ResolveRequestCache += new EventHandler(application_ResolveRequestCache);

                application.PreSendRequestHeaders += new EventHandler(application_PreSendRequestHeaders);

                application.PreSendRequestContent += new EventHandler(application_PreSendRequestContent);

            }

            void application_PreSendRequestContent(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

               application.Context.Response.Write("application_PreSendRequestContent<br/>");

            }

            void application_PreSendRequestHeaders(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_PreSendRequestHeaders<br/>");

            }

            void application_ResolveRequestCache(object sender, EventArgs e)
            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_ResolveRequestCache<br/>");

            }

            void application_AuthorizeRequest(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_AuthorizeRequest<br/>");

            }

            void application_AuthenticateRequest(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_AuthenticateRequest<br/>");

            }

            void application_AcquireRequestState(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_AcquireRequestState<br/>");

            }

            void application_ReleaseRequestState(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_ReleaseRequestState<br/>");

            }
            void application_PostRequestHandlerExecute(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_PostRequestHandlerExecute<br/>");

            }

            void application_PreRequestHandlerExecute(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_PreRequestHandlerExecute<br/>");

            }

            void application_EndRequest(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_EndRequest<br/>");

            }

            void application_BeginRequest(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.Context.Response.Write("application_BeginRequest<br/>");

            }

           

            #endregion

        }

    }

    从运行结果可以看到,在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。注:系统默认那几个HttpModule是最先衩ASP.NET Framework所加载上去的。

    示例3:(代码类同示例2


     


    HttpModule中终止此次的HTTP请求

    可以利用HttpModule通过调用HttpApplication.CompleteRequest()方法实现当满足某一个条件时终止此次的HTTP请求。

    需要注意的是,即使调用了HttpApplication.CompleteRequest()方法终止了一个HTTP请求,ASP.NET Framework仍然会触发HttpApplication后面的这3个事件:EndRequest事件、PreSendRequestHeaders事件、PreSendRequestContent事件。

    如果存在多个自定义的HttpModule的话,当Module1终止了一个HTTP请求,这个HTTP请求将不会再触发Module2中相应的事件了,但Module2的最后三个事件仍会被触发。

    示例4

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Web;

    namespace MyHttpModule

    {

        public class CompleteRequestHttpModule : IHttpModule

        {

            #region IHttpModule 成员

            public void Dispose()

            {}

            public void Init(HttpApplication application)

            {
             

                application.BeginRequest += new EventHandler(Application_BeginRequest);

            }

            void Application_BeginRequest(object sender, EventArgs e)

            {

                HttpApplication application = (HttpApplication)sender;

                application.CompleteRequest();

                application.Context.Response.Write("请求被终止。");

            }

            #endregion

        }

    }



    说明:
    那我们可以在这里做多少件事情呢?看下面的表就可以得出结论.

    事件

    说明

    BeginRequest

    指示请求处理开始。

    AuthenticateRequest

    PostAuthenticateRequest

    封装请求身份验证过程。

    AuthorizeRequest

    PostAuthorizeRequest

    封装请求授权过程。

    ResolveRequestCache

    PostResolveRequestCache

    封装检查是否能利用以前缓存的输出页面处理请求的过程。

    PostMapRequestHandler

    指示已发现用于处理请求的 HTTP 处理程序。

    AcquireRequestState

    PostAcquireRequestState

    封装对请求会话状态的检索。

    PostRequestHandlerExecute

    指示用于处理请求的 HTTP 处理程序已执行。

    ReleaseRequestState

    PostReleaseRequestState

    封装对请求会话状态的发布。

    UpdateRequestCache

    PostUpdateRequestCache

    封装检查是否应对请求的资源的输出进行缓存以备今后重复使用的过程。

    EndRequest

    指示请求处理结束。

    我们可以根据相应的事件来进行处理.做了这么长时间才发现你没想到的微软都替你想到了.

     

    在httpModule中到底要做什么?我根据一个朋友的文章写了个根据配置文件来验证页面的连接字符串的传参个数和传参的内容是否符合标准的例子.

    还有个朋友给我说了,这个可以用来修改跳转Url的改写.

    在CommunityServer中还用httpModule做了当异常处理的时候进行程序异常的页面打印的操作.

    AuthenticateRequest 请求身份验证和AuthorizeRequest请求授权过程的操作.

     

    那httpModule可以用在url重写,异常处理,身份验证等.

  • 相关阅读:
    C51 使用端口 个人笔记
    C51 静态数码管 个人笔记
    C51 矩阵按键 个人笔记
    C51 蜂鸣器 个人笔记
    C51 独立按键 个人笔记
    C51 中断 个人笔记
    CC3200 TI 笔记
    iar修改包含路径的方法
    WCF绑定和行为在普通应用和SilverLight应用一些对比
    用批处理来自动化项目编译及部署(附Demo)
  • 原文地址:https://www.cnblogs.com/zgqys1980/p/1250337.html
Copyright © 2020-2023  润新知