Asp.net生命周期

asp.net生命周期一直就想对他彻底的动手搞清楚了。以前一直处于朦朦胧胧的认识状态,今天终于下狠心动手做了个例子来了解生命周期过程。之所以打算自己动手做是因为我一直觉得虽然网上有了类似的例子,不过只有自己亲手做一遍然后通过博客写出来才能使自己更深刻的理解这些内容。好了,不废话了,开始做。

编写代码

先来看一下整个项目的结构以便对我们做的例子有一个大体的了解。项目中我定义了一个module,handler,global和一个页面以及自定义的一个控件。因为有的过程中没法直接使用Response方法,为了记录页面中事件的信息我使用了Logger这个类来专门记录信息,这是类采用了单例设计模式。来看一下他的代码:

    public class Logger
    {
        private static Logger _logger;
        private static object _o = new object();
        public static String _tempInfo;   //记录临时信息,页面卸载后将被清空
         public static String _showInfo;   //页面卸载时_tempInfo中的信息将被传递过来用于显示

         private Logger()
        {
        }

        public static Logger GetInstance()
        {
            lock (_o)
            {
                if (_logger != null)
                {
                    return _logger;
                }
                else
                {
                    _logger = new Logger();
                    return _logger;
                }
            }
        }

        public void WriteInfo(String info)
        {
            _tempInfo += String.Format("<p>{0}</p>",info);
        }

        public void WriteInfo(String info,string color)
        {
            _tempInfo += String.Format("<p style=\"color:{0};\">{1}</p>", color, info);
        }
    }

有了这个类我们就方便了各个过程的记录了。下面就在各个页面中增加记录代码,大概的格式样子是这样子的:

          Logger l = Logger.GetInstance();
         l.WriteInfo("Application_Start","blue");

同时为了了解自定义控件中的顺序我们自定义了一个简单的控件,它实现了IPostBackDataHandler,IPostBackEventHandler这样就能看到控件回调引起的数据处理和事件处理了。另外自定义的module的Init方法中也被记录了信息(代码就不贴出来了,大家看后面的源码,对module不了解的建议谷歌一下)。

分析结果

将global和页面里面的各个事件都记录信息后运行程序如下:

        

      

页面中我放了两个自定义的控件,所以会显示两次。从上面的四幅图我总结了以下几点:

1.Application_Start是指网站重新编译,重启等情况下第一次被人访问时激发。

  以后所以都不会被执行到(由1,2,3副图片对比可以看出)也就是说执行且执行一次。通常可以定义一些全局变量。

2.Session_Start是某个用户在某个会话期中第一次访问激发的。

    如上图第一副图片中我们在chrome下第一次访问页面session_start被激发,然后再通过chrome访问这个页面时(第二副图片)session_start就不被激发了。而当我们再用firefox打开这个页面时session_start又被激发了。由此可以验证我们的猜想。Session_Start方法通常用于设置某人的一些信息到SESSION,或触发用户访问计数等

3.Application_BeginRequest,Application_BeginRequest每次请求,不管用户是不是第一次访问,页面是不是回发等等。

    利用这个特点一般可以在Application_BeginRequest中进行URL重写。而Application_BeginRequest看名字也知道了,可以在其中进行权限验证等等操作。

4.控件数据回发的流程

页面OnInit事件中调用各个控件的LoadPostData方法加载从页面发过来的控件值。然后在Page_Load后调用各个控件的RaisePostDataChangedEvent的事件(我们在LoadPostData人为返回了TRUE,所以该方法一定会被执行)来完成对应的数据更改事件。

5.控件事件回发触发的时机

   从第三幅图可以看到控件是在数据回发事件后进行的。这点也可以从第二副图看出来,Button1_click事件就在数据回发后进行的。笼统一点说就是控件的状态更改都在page_load后进行。

6.为什么Application_BeginRequest会执行两次?

   大家也看到了,很奇怪的是我们明明就请求了一个页面,页面中也没有其他的图片请求。为什么Application_BeginRequest会被执行了两次呢?!既然他请求,那我们看看他到底在请求什么就是了?在Application_BeginRequest代码中将”HttpContext.Current.Request.Path”记录显示文件中。然后执行显示如下:

以前也一直没有注意到这方面的内容。原来默认回去请求网站的图标啊。没文化了^_^!我找了个图片放到网站根目录下,再次刷新浏览器有效果了:

7.整个页面的执行过程

   第一副图就是最好的例子,不过感觉还是要再总结一下(可能事件有点少,不过重要的都画出来了):

  

还没有结束

上面只是从我们的编码能够涉及到的地方看了下asp.net的执行流程。那么在这之前呢?就是从IIS接受到这个请求到我们上面讲到的这之间的过程又是如何的呢?

借用网上的一张图片来说明一下:IIS会首先根据请求地址的映射将其提交到aspnet_isapi.dll(具体的映射关系可以在IIS中设置),然后经过中间的一些COM组件(详细说起来还是蛮复杂的,具体可以看这篇文章)到达ISApiRuntime,在这里请求将会被路由到ISAPIRuntime.ProcessRequest()方法里。这个方法会接着调用HttpRuntime.ProcessRequest,这个方法会为请求创建了一个新的HttpContext实例然后获取一个HttpApplication实例并调用HttpApplication.Init()初始化管道事件。于是这样就到了我们上面的Global.ascx定义的各个方法中。

看起来可能简单,不过还是很复杂的。这些过程都不是我们能够控制的,所以我觉得了解一下就可以了。真正掌握的还是上面的几个过程。

好了,说的也差不多了。以后这上面有新的体会再补充吧。奉上测试代码!

源码下载

时间: 2024-10-20 00:36:48

Asp.net生命周期的相关文章

ASP.NET生命周期详解 [转]

最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等,对于ASP.NET MVC同样适用.只是MVC URLRouting Module对进入到server的request进行了拦截,然后对此次request的handler进行了特殊的处理.总结来说,就是 ASP.NET管道是所有ASP.NET Web Applicaiton,包括WebForm,

Asp.Net生命周期和Http管道技术

本篇主要介绍一下内容: 1.ASP.NET生命周期 2.Http运行时 3.Http管道技术 a)inetinfo.exe b)asp.net_isapi.dll c)aspnet_wp.exe d)HttpHandler e)HttpModule 4.实现Httphandler的使用 5.ASP.NET生命周期 6.(IIS)Web服务器(inetinfo.exe): 1.只有少数几种被客户端请求的资源类型由iis直接处理,如对Html页面,文本文件,jpeg和gif图像的传入请求 2.对AS

Asp.Net生命周期系列一

Asp.Net生命周期对于初级甚至中级程序员来说,一直都是一个难题,很多程序员不了解生命周期,导致使用Asp.Net做开发感觉很不灵活,感觉太多东西被微软封装好了,我们不能改变,其实只要你稍微了解一下就知道,原来不是这样的! 我写这一系列文章是采用总分的方式,先让大家整体了解,然后再逐一突破.先将一个故事,也是园子里看到的(http://www.cnblogs.com/GodSpeed/archive/2010/06/19/1761095.html),我认为这个写的有些细节上的错误,稍稍添加些自

ASP.NET Page执行顺序(ASP.NET生命周期)

此部分说明的生命周期只有部分: ---引用MSDN 阶段 说明 页请求 页请求发生在页生命周期开始之前.用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进行响应. 开始 在开始阶段,将设置页属性,如 Request和 Response在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性.此外,在开始阶段期间,还将设置页的 UICulture 属性. 页初始化 页初始化期间,可以使用页中的

[译] ASP.NET 生命周期 – ASP.NET 上下文对象(五)

ASP.NET 上下文对象 ASP.NET 提供了一系列对象用来给当前请求,将要返回到客户端的响应,以及 Web 应用本身提供上下文信息.间接的,这些上下文对象也可以用来回去核心 ASP.NET 框架特性. 上下文对象提供了应用,当前请求,与当前请求相关联的响应的信息.也提供了对多数重要的 ASP.NET 平台服务的访问,比如安全与状态数据.我们可以在 MVC 框架的 controllers 和 views 中使用上下文对象来根据当前的请求或者应用状态数据来调整我们应用的响应.在创建模块或者处理

[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(四)

不使用特殊方法来处理请求生命周期事件 HttpApplication 类是全局应用类的基类,定义了可以直接使用的一般 C# 事件.那么使用标准 C# 事件还是特殊方法那就是个人偏好的问题了,如果喜欢,也可以将这两种方式混合起来使用. 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.W

[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(三)

使用特殊方法处理请求生命周期事件 为了在全局应用类中处理这些事件,我们会创建一个名称以 Application_ 开头,以事件名称结尾的方法,比如 Application_BeginRequest.举个例子,就像 Application_Start 和 Application_End 方法,ASP.NET 框架就会在事件触发的时候找到这些函数并触发它.下面是更新后的代码片段: 1 using System; 2 using System.Collections.Generic; 3 using

ASP.NET 生命周期 – ASP.NET 应用生命周期(一)

概述 ASP.NET 平台定义了两个非常重要的生命周期.第一个是 应用生命周期  (application life cycle),用来追踪应用从启动的那一刻到终止的那一刻.另一个就是 请求生命周期 (request life cycle),它定义了 HTTP 请求在 ASP.NET 平台中首次接收到,到最终响应发出之间的路径. ASP.NET 应用生命周期 在 ASP.NET 中有两个时刻——应用启动的时刻和应用停止接收请求的时刻,这两个时刻定义了应用生命周期.ASP.NET 在应用启动和当应

【IHttpHandler】ASP.NET 生命周期

对由 Microsoft? Internet 信息服务 (IIS) 处理的 Microsoft? ASP.NET 页面的每个请求都会被移交到 ASP.NET HTTP 管道.HTTP 管道由一系列托管对象组成,这些托管对象按顺序处理请求,并将 URL 转换为纯 HTML 文本.HTTP 管道的入口是 HttpRuntime 类.ASP.NET 结构为辅助进程中的每个 AppDomain 创建一个此类的实例.(请注意,辅助进程为每个当前正在运行的 ASP.NET 应用程序维护一个特定的 AppDo