【向everyone提问】很想知道asp.net的一个关于生命周期的问题
首先在页面请求过程时从PreInit到StateComplete的执行顺序是什么,他们都分别做了些什么事呢。
我们在动态加载一个TextBox等控件的时候,当页面回执的时候很轻松的可以找到它,而在加载一个UserControl的时候则需要每次Load的时候都要加载,因此想知道控件的生命周期和用户控件的工作原理
其次整个站点从Application_Start到Application_End,又都做了些什么,除了Application对象外,还有什么是一直保存在内存中呢
问题描述的不好,如果有不清楚问题的请跟帖
多谢各位的指教
------解决方案--------------------我记得有些阶段执行顺序不是固定的
------解决方案--------------------生命周期我觉得主要能分成一下几个阶段,按照发生的时间顺序
1、初始化页面框架
这个过程触发page.Init事件,这个是在各种事件被触发时都会运行的。不过需要注意的是,正如他的名字那样,这个时候是对页面框架的初始化,所以是无法进行UI行为的。
2、应用程序代码初始化
这个过程对应的事件是Page_Load,在这个事件中asp.net是会判断页面是回发还是首次加载的。不过,尽管如此Page_Load在各种事件被触发时都会运行的。所以,可以通过IsPostBack来进行写辅助操作。
3、执行事件处理
如果是首次加载则会不运行用户触发的事件,如Click事件等。则是直接执行Page_PreRender事件。此时整个过程主要事件顺序为Page_Init-Page_Load-Page_PreRender
如果是用户触发了事件,如发生了Click操作,则整个过程将会变成 Page_Init-Page_Load-Click事件-Page_PreRender
------解决方案--------------------http://www.cnblogs.com/me-sa/archive/2008/03/17/LifeCycle.html
http://blog.csdn.net/dw4736/archive/2009/04/22/4101525.aspx
------解决方案--------------------
1.对象初始化
页面中的控件(包括页面本身)都是在它们最初的FORM中被首次初始化的。通过在ASPX页面的后台代码文件的构造器中声明你的对象,页面将知 道对象的类型,并知道需要创建多少个这样的对象。一旦你在构造器中声明了你的控件,你就可以在它的任何子类,方法,事件或者属性中访 问到它们。但是,如果你的任何对象是在ASPX文件中指定的控件,这样的控件是没有属性的。而且这样做对从代码中访问它们是危险的,因为 无法保证这些控件实例是按照怎样的顺序被创建的(假定它们都是能完全被创建的)。初始化事件可以通过OnInit方法重载。
2.加载视图状态数据
初始化以后,控件仅能通过ID引用(还没有建立用于相对引用的文档对象模型)。 在LoadViewState事件中,已初始化的控件获得第一个属性: 上一次提交存留到服务器的视图状态信息。页视图状态通过ASP.NET维护,它被用于在一个往返行程中存留信息到服务器。视图状态信息被保存 为一个名称/值对,它包含控件的如Text和Value一类的信息。视图信息被保存在隐藏<input>控件的值属性中在页请求中传递。正如你所了解的 ,这是旧的ASP3.0状态维护技术的一个巨大飞跃。这个事件可以通过LoadViewState方法重载,往往用来在控件被填充时定制它所接受的数据。
3.LoadPostData处理回传数据
在创建页的阶段,被发送到服务器端的Form数据(ASP.NET中的术语为回传数据)依照每个控件的数据需求进行处理。当页面提交Form时,框架将 在每个提交数据的控件上实现IPostBackDataHandler接口。页面然后激发LoadPostData事件,通过页面解析发现实现了 IPostBackDataHandler 接口的控件,并用正确的回传数据更新控件状态。ASP.NET通过匹配控件的唯一标示符来更新正确的控件,该标示符具有名称值集合中的名称值 对。这也就是在所有特定的页中每个控件都需要一个唯一标示符的原因之一。其它的步骤都由框架来完成,以确定每个标示符在环境中是唯一的,例如存在于单页面 中的自定义用户控件。LoadPostData事件被激发后,RaisePostDataChanged事件就可以随时被执行了。
4.对象加载
对象在Load事件中获得正确的Form。所有的对象首先都被组织在页DOM(ASP.NET中称为控件树)中,并且很容易通过代码或者相对位置(crawling the DOM)来引用。然后对象就可以自由的访问HTML中的客户端属性集,例如width,value,或者visibility。加载时,控件逻辑,如算法、以编 程方式设置控件属性、用StringBuilder装配输出字符串都同时被执行。大部分的工作都是在这一阶段完成的。Load 事件能够通过调用OnLoad来重载。
5.激发RaisePostDataChanged事件
如前所述,这发生在所有实现了IPostBackDataHandler接口的控件被正确的回传数据更新以后。在这个过程中,每个控件都有一个布尔值的标 识,标识其自上一次提交后该控件的数据是被更改还是保持原值。然后ASP.NET通过搜索页来寻找任何显示控件数据被更改的标识并激发
RaisePostDataChanged。RaisePostDataChanged事件直到Load事件发生后,所有控件被更新后才激发。这保证了在控件被回传数据更新前,其它控件的数据在RaisePostDataChanged事件中没有被手动更改过。
6.处理客户端回传事件
当回传更新导致数据改变而引发服务器端事件后,引发回传的对象会在RaisePostBackEvent事件中被处理。这种激发回传的对象往往是其状态改 变而引发回传的控件(其autopostback被启用)或者是一个被点击的窗体提交按钮。很多代码都在这个事件中执行,因为这是控制事件驱动逻辑的理想 位置。为了保证呈现到浏览器的数据的正确性,在一系列的回传事件后RaisePostBackEvent事件最终被激发。基于一致性的考虑,回传中改变的 控件直到这个函数被执行后才被更新。也就是说,被预期事件改变的数据总是在结果页反映出来。RaisePostBackEvent事件可以通过 RaisePostBackEvent来捕捉。
7.对象预呈现
对象被预呈现的地方对于那些能够保存到视图或者维持其视图状态的对象来说是最后一次有机会改变的地方。这使得预呈现步骤成为做最后修改的理想位置,例如改 变控件属性或改变控件树结构,不用担心因为数据库请求或者视图状态更新而导致对象的变化。预呈现阶段之后,对象改变被锁定并且不能再被保存到页视图状态 中。预呈现阶段可以通过重载OnPreRender实现。
8.保存视图状态
只有在所有的页面对象的改变都发生后视图状态才被保存。对象状态数据被保存在隐藏<input>对象中,这也是对象状态数据准备呈现到 HTML的地方。在SaveViewState事件中,值能够被保存到视图状态对象中,但页面控件的改变并不能保存到其中。可以通过重载 SaveViewState实现这个步骤。
9.呈现HTML
Render事件通过装配用于浏览器输出的HTML来着手页的创建。在Render事件中,页调用对象使它们呈现为HTML,然后页收集HTML来发送。 当Render事件被重载的时候,开发者可以为浏览器创建定制的HTML,此时页面创建的任何HTML都还没有生效。Render 方法用HtmlTextWriter对象作参数并由它产生HTML给浏览器。这里仍然可以作修改,但是这样的修改只会反映到客户(译者注:意即改变只会在 HTML呈现中反映而视图状态并无法被改变)。Render 事件可以被重载
10.释放
当页面的HTML呈现后,对象被释放。在Dispose事件中,你可以清除任何在页面创建中构造的对象或者引用。在这里,所有的处理都已经被执行,你可以安全的释放任何还存在的对象,包括Page对象。