zoukankan      html  css  js  c++  java
  • ASP.NET应用程序生命周期趣谈(三)

    ASP.NET应用程序生命周期趣谈(三) HttpModule

    在之前的文章中,我们提到过P_Module(HttpModule)这个能干的程序员哥们儿,它通过在项目经理HttpApplication那里得到的授权,插手整个应用程序级别的事件处理。所有的HttpModule都要实现IHttpModule接口,那么我们看IHttpModule的定义:

    namespaceSystem.Web

    {

        public interface IHttpModule

        {

            voidDispose();

            voidInit(HttpApplicationcontext);

        }

    }

    可以看到,HttpModule主要就做了两件 事,一个就是大家都明白的释放资源Dispose(),另一个则是初始化。用什么初始化呢?当然是HttpApplication。刚才已经说 过,P_Module程序员是经过了项目经理HttpApplication的授权了的,这里我们就可以看到,初始化方法参数就是 HttpApplication对象,那么HttpModule又是怎么处理应用程序级别的事件的呢?且看:

    我们可以看到,项目经 理HttpApplication可是实实在在的放权啊,它非常的相信P_Module可以做好这些事情,所以在初始化方法 Init(HttpApplication context)中,程序员P_Module可以注册很多事件,比如说常用的BeginRequest, EndRequest, AuthenticateRequest, AuthorizeRequest等等,还有一些其它的不常用的事件我们就不再赘述。总而言之,HttpModule强大到可以插手整个应用程序周期的所 有事件---因为得到了充分授权嘛。下面是注册BeginRequest事件示例代码:
     public void Init(HttpApplication context)

     {

         context.EndRequest+= new EventHandler(context_EndRequest);

     }

     private void context_EndRequest(object sender, EventArgs e)

     {

        //do something when the request end

     }

    那么这里,我们要澄清一个问题:在ASP.NET应用程序生命周期趣谈(一)中我们曾经在后面提到“P_Handler自信的笑了一声,把箱子交还给了项目经理(HttpApplication对象)”,这 是不完全准确的。事实上P_Module已经是一个非常高级的程序员,他在有必要的情况下(注册了EndRequest事件)是要review初级程序员 P_Handler的工作的,这个review的事件就是HttpApplication的EndRequest的事件。当然,有时候也不review就 直接交给HttpApplication了,所以我们得出结论:ASP.NET请 求处理是基于管道模型的,request从管道这头进去,经过了HttpModule的一些列处理,到那头儿的HttpHandler再处理,最后再经过 管道原路返回。一次请求HttpHandler只能有一个,而HttpModule却可以有若干个。(ps: --!真是废话,MSND上写的比谁都清楚)

    总的来说,P_Module高级程序员主要就是从 项目经理HttpApplication那得到授权(传入HttpApplication参数)处理应用程序级别的一些重要事件,这些事件贯穿整个应用程 序生命周期。我们经常会使用到ASP.NET自带的HttpModule,也有时会使用自定义的HttpModule。ASP.NET自带的 HttpModul在以下目录中可以找到:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 \CONFIG/web.config

    而我们自己编写的自定义HttpModule则写在我们的应用程序的web.config文件中,也是<HttpModules></HttpModule>节点下,与系统自动配置的并无不同:

    可以看 到,<HttpModules>节点是在system.web下面的,HibernateUtil就是我曾经写过的一个 HttpModule,非常典型,大家可以参考。对与系统自带的HttpModule有很多,这里我就随便挑了一个SessionStateModule 来给大家做一个大致的分析,以便大家了解HttpModule如何工作。

    简单说一下什么事SessionState。 SessionState就是asp.net处理Session的一种机制,简单来说就是它通过管理Session的存储位置,来优化Session的性 能和安全性,避免浏览器禁用cookie时session丢失。ASP.NET允许Session存储在三个位置:aspnet_wp.exe(它崩溃 session就丢失);aspnet_state.exe(单独的stateserver);sqlserver(存到数据库中)。关于 SessionState的内容,请参阅其它相关文章,以后有机会我自己也会写写。

    书归正传,那么我们通过反编译SessionStateModule,我们得到两行有用的代码:

            public voidInit(HttpApplication app)

            {

                SessionStateSection sessionState = RuntimeConfig.GetAppConfig().SessionState;

    //从config文件中读取SessionState配置

                this.InitModuleFromConfig(app, sessionState);

    //初始化SessionStateModule需要处理的事件

    //Other Code

            }

    第一行从config文件中读取了SessionState的配置(节点<configuration><system.web><sessionState>下面的内容,配置了怎么存储Session等信息),第二行则初始化了SessionStateModule需要处理的事件,我们再看看InitModuleFromModule干了什么:

    private void InitModuleFromConfig(HttpApplication app, SessionStateSection config)

    {

    if (config.Mode != SessionStateMode.Off)

            {

                app.AddOnAcquireRequestStateAsync(new BeginEventHandler(this.BeginAcquireState), new EndEventHandler(this.EndAcquireState));

                app.ReleaseRequestState += new EventHandler(this.OnReleaseState);

                app.EndRequest += new EventHandler(this.OnEndRequest);

            }

    }

    我们可以看到,第一行 代码中,HttpApplication添加了OnAcquireRequestState的若干事件的处理方法,第二行添加了当 SessionState释放时的处理方法,第三行则添加了request接触时的处理方法。SessionStateModule内部如何处理我们这里 不做详述,但是我们可以清晰的看到,SessionStateModule处理了应用程序级别的时间,包括SessionState的获得,释放和 Request的结束。我们没有发现它处理开始Request的事件,但我们确信它是有能力去做的,只是此种情形下并不需要那么做。下面按照执行顺序列出 HttpApplication的事件列表以供参考:

    1.     BeginRequest   //开始

    2.     AuthenticateRequest //验证

    3.     AuthorizeRequest //授权

    4.     AcquireRequestState //获取request state

    5.     ReleaseRequestState //释放request state

    6.     UpdateRequestCache //更新cache

    7.     LogRequest.   //这个事件只支持.net 3.0以上版本和IIS7的集成模式

    8.     EndRequest //结束

    有的HttpModule(包括自定义的和系统自带的)均有能力处理这些事件从而对应用程序产生影响,看来这个P_Module程序员果然很牛啊,项目经理信任它并授权也是有道理的。

    然后P_Module作为一个高级程序员,它 自身知识积累固然很强大,它的学习能力也是不可忽视的。它可以自己学习(创建)一些新的能力(自定义Module),经典的例子就是它网上盛传的它能在每 个页面中都加入一些文字;这里我只简单的说明我用过的一个P_Module自建的在EndRequest事件中关闭NHibernateSession的 例子:

    首先,我们创建一个类HibernateUtil,继承接口IHttpModule,并实现接口方法:

     

    public class HibernateUtil: IHttpModule

    {

        public void Dispose()

        {

        }

     

        public void Init(HttpApplication context)

        {

        }

    }

    然后,注册EndRequest事件:

     public voidInit(HttpApplication context)

     {

          context.EndRequest+= new EventHandler(context_EndRequest);

     }

     private void context_EndRequest(object sender, EventArgs e)

     {

          CloseSession();

     }

    最后,配置Web.config:

    此时,我们就完成了一个自定义的HttpModule。这个小例子并不难,主要是说明了HttpModule的创建流程和方法,而本篇文章也难度也不是很高,希望对大家能有所帮助,欢迎拍砖,少扔鸡蛋,挺贵的,谢谢! ^_^

     

    相关链接:

    ASP.NET应用程序生命周期趣谈(一)

    ASP.NET应用程序生命周期趣谈(二)

  • 相关阅读:
    C++自定义异常类
    上下栏固定, 中间滚动的HTML模板
    C# 代理应用
    C# 对象池的实现(能限制最大实例数量,类似于WCF的MaxInstanceCount功能)
    半同步半异步模式的实现
    EventBus实现
    C Socket初探
    C Socket初探
    VC++全屏
    MFC 坦克定位
  • 原文地址:https://www.cnblogs.com/wenghaowen/p/2683819.html
Copyright © 2011-2022 走看看