Aspx 页面生命周期

ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤。这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行呈现。了解页的生命周期非常重要,这样就能在合适的生命周期阶段编写代码,以达到预期效果。此外,如果开发自定义控件,则必须熟悉页生命周期,从而正确地初始化控件,使用视图状态数据填充控件属性以及运行所有控件行为逻辑。(控件的生命周期基于页的生命周期,但是页引发的控件事件比单独的 ASP.NET 页中可用的事件多。)

常规页生命周期阶段

一般来说,页要经历下表概述的各个阶段。除了页生命周期阶段以外,还有在请求前后出现的应用程序阶段,但是这些阶段并不特定于页。有关更多信息,请参见 ASP.NET 应用程序生命周期概述。

阶段说明

页请求

页请求发生在页生命周期开始之前。用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进行响应。

开始

在开始阶段,将设置页属性,如 Request 和 Response。在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性。此外,在开始阶段期间,还将设置页的 UICulture 属性。

页初始化

页初始化期间,可以使用页中的控件,并将设置每个控件的 UniqueID 属性。此外,任何主题都将应用于页。如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚未还原为视图状态中的值。

加载

加载期间,如果当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性。

验证

在验证期间,将调用所有验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性。

回发事件处理

如果请求是回发请求,则将调用所有事件处理程序。

呈现

在呈现期间,视图状态将被保存到页,然后页将调用每个控件,以将其呈现的输出提供给页的 Response 属性的 OutputStream。

卸载

完全呈现页、将页发送至客户端并准备丢弃时,将调用卸载。此时,将卸载页属性(如 ResponseRequest)并执行清理。

生命周期事件

在页生命周期的每个阶段中,页将引发可运行您自己的代码进行处理的事件。对于控件事件,通过以声明方式使用属性(如 onclick)或以使用代码的方式,均可将事件处理程序绑定到事件。

页还支持自动事件连接,即,ASP.NET 将寻找具有特定名称的方法,并在引发特定事件时自动运行这些方法。如果 @ Page 指令的 AutoEventWireup 属性设置为 true(或者如果未定义该属性,因为默认情况下为 true),页事件将自动绑定至使用 Page_event 命名约定的方法,如 Page_LoadPage_Init。有关自动事件连接的更多信息,请参见 ASP.NET Web 服务器控件事件模型。

下表列出了最常用的页生命周期事件。实际的事件比列出的事件要多。但是,它们不用于大多数页处理方案。而是主要由 ASP.NET 网页上的服务器控件使用,以初始化和呈现它们本身。如果要编写自己的 ASP.NET 服务器控件,则需要详细了解这些阶段。有关创建自定义控件的信息,请参见开发自定义 ASP.NET 服务器控件。

页事件典型使用

Page_PreInit

  • 使用 IsPostBack 属性确定是否是第一次处理该页。

  • 创建或重新创建动态控件。

  • 动态设置主控页。

  • 动态设置 Theme 属性。

  • 读取或设置配置文件属性值。

    Note注意

    如果请求是回发请求,则控件的值尚未从视图状态还原。如果在此阶段设置控件属性,则其值可能会在下一阶段被改写。

Page_Init

  • 读取或初始化控件属性。

Page_Load

  • 读取和更新控件属性。

Control events

执行特定于应用程序的处理:

  • 如果页包含验证程序控件,请在执行任何处理之前检查页和各个验证控件的 IsValid 属性。

  • 处理特定事件,如 Button 控件的 Click 事件。

Page_PreRender

  • 对页的内容进行最后更改。

Page_Unload

执行最后的清理工作,可能包括:

  • 关闭打开的文件和数据库连接。

  • 完成日志记录或其他特定于请求的任务。

    Note注意

    在卸载阶段,页及其控件已被呈现,因此无法对响应流做进一步更改。如果尝试调用方法(如 Response.Write 方法),则该页将引发异常。

其他的页生命周期注意事项

请注意有关页生命周期的以下附加信息:

  • 各个 ASP.NET 服务器控件都有自己的生命周期,该生命周期与页生命周期类似。例如,在相应的页事件期间将调用控件的 InitLoad 方法。如果页上包含控件,则将首先调用控件的 Init 方法,然后再调用页的 Init 方法。但是,将在调用控件的 Load 方法之前先调用页的 Load 方法。

  • 通过处理控件的事件,可以自定义控件的外观或内容。例如,所有的控件都将引发 InitLoadUnload 事件,但是页开发人员通常不处理这些事件。而是通常处理特定于控件的事件,如 Button 控件的 Click 事件和 ListBox 控件的 SelectedIndexChanged 事件。在某些情况下,可能也需处理控件的 DataBindingDataBound 事件。有关更多信息,请参见各个控件的类参考主题以及开发自定义 ASP.NET 服务器控件。

  • 除了处理由页引发的事件以外,还可以重写页的基类中的方法。例如,可以重写页的 InitializeCulture 方法,以便动态设置区域性信息。注意,在使用 Page_event 语法创建事件处理程序时,将隐式调用基实现,因此无需在方法中调用它。例如,无论是否创建 Page_Load 方法,始终都会调用页基类的 OnLoad 方法。但是,如果使用 override 关键字(在 Visual Basic 中为 Overrides)重写页的 OnLoad 方法,则必须显式调用基方法。例如,如果在页中重写 OnLoad 方法,则必须调用 base.Load(在 Visual Basic 中为 MyBase.Load)以运行基实现。

具体阶段执行函数的顺序
  • 初始化(Initialization)

    页面被请求时,第一个被执行的总是构造函数(constructor). 你可以在这里初始化很多自定义属性或对象。不过这里有一些限制,因为 page 还没有被完全初始化。特别地,你必须使用 HttpContext.Current 来访问 QueryString, Form, Cookies 集合,以及 Cache 对象。而 Session 对象在 constructor 里是无法访问的。

    下面接着执行的是 AddParsedSubObject 方法,这个方法把组成该 page 的所有子控件添加到控件集合树中。在很多高级的页面模板解决方案中,该方法通常被覆盖,以便把页面的控件添加到一个特殊的页面模板中去。该方法递归的被子控件调用,所有这些子控件都是这时候初始化的,从最里面的开始。

    接着是 DeterminePostBackMode 方法。该方法允许你影响 IsPostBack 的值,以及相关事件。如果你想从数据库中加载 ViewState 以便 redirect 时,这个可能对你有用。因为 ViewState 仅仅在 IsPostBack 为 true 的时候被恢复。 你可以通过返回 null 来强制不 postback, 或者返回 Request.Form 来强制 postback. 这个方法是不推荐使用的,除非是在特殊的情况下,因为他还影响其他的事件。

    然后是 OnInit 方法。通常这是我们使用到的第一个方法。这时,所有控件已经被初始化,也就是说所有原始值都被设定了。而 ViewState 以及所有其他 post 的值还没有被应用到控件上。也就是说这时候所有通过代码或者用户操作做的更改还没有被恢复。这通常是创建或重新创建动态控件的最佳时机。

    恢复和加载(Restore and Load)

    接下来的 LoadPageStateFromPersistenceMedium 方法,仅仅在 PostBack 时被执行。当你要改变保存 ViewState 的方法时(使用 Session 或其他自定义的储存方法),覆盖这个方法,以及后面的 SavePageStateToPersistenceMedium 方法。注意:该方法并不真正加载 ViewState 到 page 及其子控件。

    ViewState 被取回后,接着 LoadViewState 方法将它们恢复到 page, 并递归的恢复到每一个子控件(只有 PostBack 的那些).这时,每个控件已经被恢复到了它上次执行时的状态,但用户 post 的值还没有被应用。因为这属于 ViewState. 这个方法是恢复所有在事件中创建的动态控件的最好时机。

    下一个是 ProcessPostData 方法。仅仅在 PostBack 时被执行。而且这个方法不能被覆盖,因为它是页面基类中实现的一个私有方法。这个方法最终将用户 post 的值,通过匹配控件的名称的方法,恢复到页面。这时,page 已经被完全恢复了。动态控件必须在这个方法之前被创建。这个方法同时也为稍后的 changed 事件记录控件值的改变。

    然后才是 OnLoad 方法。大部分的代码中都使用这个方法,因为这是在 page 的生命周期中,第一个所有的值都被恢复了的地方。我们可以通过检查 IsPostBack 属性来避免不必要的重设状态。同时也可以检查 IsValid 属性来进行验证。同时还可以在这里创建动态控件。所有这些控件的方法都会被执行并捕获,包括 ViewState. 但回发的值不可以。

    Raised Events

    下一个方法,ProcessPostData 方法,实际上是前面那个方法的第二个入口(second pass)。它仅仅处理回发,而且由于是私有方法,所以不能被覆盖。这个方法显得有些奇怪,但又是必要的。因为在 OnLoad 方法中重建的动态控件需要他们回发的值。所有在这个方法之后创建的动态控件,将只能恢复 ViewState, 而不能恢复回发的值,并且不能触发任何更改事件。

    下一个方法, RaiseChangedEvents, 同样仅仅用于回发时。它是一个基类实现的私有方法。这时 changed 事件被真正触发。这基于前面 ProcessPostData 方法中标注出回发的值的差异。当有多个 changed 事件被触发时,其先后顺序是没有保证的。

    下面是 RaisePostBackEvent 方法。仅用于回发,而且是基类实现的私有方法。这是真正提交 form 的方法,除非是 postback。比如按钮,或者其他通过 javascript 提交的控件被触发。如果使用了 Validators, 如没有手动调用 Validate 方法,这时也已经被调用了。有时候 ie 的 bug 会使得表单被提交,而不引发事件。

    接着是 OnPreRender 方法。这通常是在被绘制到浏览器之前,要更改 page 及其子控件的最后机会。你也可以在这里创建动态控件。但这时只能捕获 ViewState, 而不能接受 posted values, 而且没有事件。因为上面提到的 ie 的 bug, 这里可以用来捕获没有触发事件的 post back.

    保存和绘制(Save and Render)

    下一个是 SaveViewState 方法。不管是否 post back. 递归的应用到每一个子控件。ViewState 一般保存所有和 aspx 页面里不一样的属性,不管是被代码还是用户更改的。注意,由于控件的值是通过他们在控件树中的位置来保存的,所以如果在这之后添加动态控件到错误的位置, ViewState 可能会崩溃。

    下面是 SavePageStateToPersistenceMedium 方法。它真正的保存 page 的 ViewState. 这个方法可覆盖。如果重写的话,注意这里由于 asp.net 的 bug, 需要手工设定一下 __VIEWSTATE,哪怕是空值。

    接着是 Render 方法。它递归的调用到每个子控件,真正的绘制各自的 html, 发送到浏览器。在一些页面模板方案中,常常在这里添加通用的 header 和 footer. 而不用使用服务器控件。 注意在这里能作的更改必须是纯的 html. 因为这时候控件都已经绘制完了。

    最后是 OnUnload 方法。它调用了 Dispose 方法。这个方法可以用来清理页面中使用的非托管资源。特别是类似于关闭打开的文件或数据库连接等。该方法只有当页面已经被发送到客户端浏览器后才发生。所以它只能对服务端的对象起作用。所以他不能在 page 的 trace 中被显示。

    上面就是 page 的生命循环。每次有一个新的请求时,以上过程就重复一次。

    Listing 1: Page 的事件小结
     
    MethodPostBackControls
    ConstructorAlwaysAll
    AddParsedSubObjectAlwaysAll
    DeterminePostBackModeAlwaysPage
    OnInitAlwaysAll

    LoadPageStateFromPersistenceMediumPostBackPage
    LoadViewStatePostBackAll
    ProcessPostData1PostBackPage
    OnLoadAlwaysAll

    ProcessPostData2PostBackPage
    RaiseChangedEventsPostBackPage
    RaisePostBackEventPostBackPage
    OnPreRenderAlwaysAll

    SaveViewStateAlwaysAll
    SavePageStateToPersistenceMediumAlwaysPage
    RenderAlwaysAll
    OnUnloadAlwaysAll

转载于:https://www.cnblogs.com/tuyile006/p/3454447.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 练习册,每天一个小程序

Python 练习册,每天一个小程序说明:Python 练习册,每天一个小程序。注:将 Python 换成其他语言,大多数题目也适用不会出现诸如「打印九九乘法表」、「打印水仙花」之类的题目点此链接,会看到每个题目的代码…

不同网段虚拟机,互相访问时的路由配置,附路由知识学习

事情实例: 虚拟主机:192.168.90.247需要访问192.168.91.XX网段的数据库,无法访问。 1、这里要考虑一下添加一个路由,目的地址为192.168.91.XX,掩码为255.255.255.0,网关为如图所示 2、这里添加一个路由为:…

iOS使用自定义字体(添加字体包)

转载请注明出处!!! 首先是最简单也普遍的做法,打包内置字符库文件: 步骤如下: 1.第一步找到你想用的字体的 ttf 格式。加入到你的工程的resouce目录下。 2.在工程的plist中AddRow,“Fonts provi…

TP5:框架下载与安装——1

哪里下载? 一、百度搜索:ThinkPHP5.0完全开发手册 可以在找到安装TP5的介绍,分别有官网下载安装、Composer安装、Git安装三种方式下载 二、下载好文件 这里我们选择了GIT方式安装,要注意的是,要同时下载应用项目和核…

游戏密保卡图片识别

识别主要步骤 1.图像预处理。包括确认图片有效区域,灰度化,二值化。 2.字符分割。即将识别信息最小化。由于密保卡图片文字宽度固定且无粘连,只需要使用固定宽度切割。 3.对分割后的信息提取特征,建立特征库 4.提取特征和特征库样本进行匹配&…

基于visual Studio2013解决C语言竞赛题之0505选数

题目解决代码及点评/************************************************************************/ /* 5. 输入N个数到数组中,选出其中最大的数和最小的数,并分别将它们与最前面和最后面的数互换 */ /*************…

TP5:缩短访问路径和路由的使用——2

一、缩短访问路径 1、如图访问该文件路径 没有缩短之前,访问的路径是 http://localhost/zerg_new/public/index.php/api/v1/banner/1 缩短后,访问的路径是 http://z_new.cn/api/v1/banner/1 2、缩短路径步骤 本机apache配置,小编使用的…

10个加速Table Views开发的Tips

2019独角兽企业重金招聘Python工程师标准>>> 本文由CocoaChina译者yake_099(博客)翻译,作者:David McGraw 原文:10 Actionable Performance Tips To Speed Up Your Table View 在我们开始之前,…

TP5:验证器的封装——5

TP5的独立验证器如图所示: $validate new Validate([name > require|max:25,email > email ]); $data [name > thinkphp,email > thinkphpqq.com ]; if (!$validate->check($data)) {dump($validate->getError()); } 现在我们把验证器的封装…

flask蓝图的使用

flask蓝图的使用 首先,我对蓝图的理解相对通俗,就是觉得蓝图对于视图方法模块化、大项目协同开发过程中的一个很好的工具. 1.下图是我们通常情况下使用的项目组织结构 看一下视图方法: #views.py1 from app import app2 3 4 app.route(/user/index)5 d…

TP5:异常处理封装——3

如果不进过异常封装,如果抛出一异常只会只会上图所示,大部分时候,用户只需要知道Division by zero就够了。 1、首先先建一个类BaseException并继承Exception,这里有三个参数 $code 400; $msg ; $errorCode ;并处理当抛出异常时的…

接口测试(java+testng+ant+jenkins)第三篇ant

1、ant是什么? 是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具 2、下载安装 http://www.cnblogs.com/yuzhongwusan/archive/2013/03/26/2982411.html 3、在eclipce中的使用 准备工作: 项目右键——new——folder——folder name: li…

KVM虚拟机IO处理过程(二) ----QEMU/KVM I/O 处理过程

接着KVM虚拟机IO处理过程中Guest Vm IO处理过程(http://blog.csdn.net/dashulu/article/details/16820281),本篇文章主要描述IO从guest vm跳转到kvm和qemu后的处理过程. 首先回顾一下kvm的启动过程(http://blog.csdn.net/dashulu/article/details/17074675).qemu通过调用kvm提供…

如何利用echarts图表获取条状图点击名称和值

如何利用echarts图表获取条状图点击名称和值 听语音 |浏览:1505|更新:2017-06-13 10:20|标签:软件 1 2 3 4 5 6 7 分步阅读 echarts图表插件工具,包含了各种不同类型的图形,有圆饼图、折线图、圆环图、柱状图…

TP5: 日志记录改造——4

TP5的日志如果没有特别设置的话,只要出现错误就会记录在日志文件中。这种是没有做必要的,因为这样的话,LOG文件会特别大,而且有好多都是没有用的信息。下面我们对LOG日志进行改造只记录我们需要的信息。 还记得上一章中&#xff…

.NET使用免费开源类库操作Excel

2019独角兽企业重金招聘Python工程师标准>>> 自从上次找到NPOI之后,根据园友提供的线索以及Google,又找到了一些开源免费的类库,所以都简单体验了一遍。 主要找到以下类库: MyXls(http://sourceforge.net/projects/m…

JMS 消息处理

转载于:https://www.cnblogs.com/luswei/p/7504781.html

设计模式(单例)

单例模式是最简单的设计模式, 意图: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 适用性: 只能有一个实例而且客户可以从一个众所周知的访问点访问它时。 当这个唯一实例应该是通过子类化可扩展的,并且客户…

牛刀小试、用SharePoint 实现请假管理功能

转:http://www.cr173.com/html/15518_1.html “请假管理”应用,应该算是 SharePoint 的“Hello World!”、川菜里面的鱼香肉丝、粤菜里面的蛋炒饭 。。。吧? 怎么样才能做出简易、实用的请假管理,一直都是都是一个问题…

django时区设置问题

2019独角兽企业重金招聘Python工程师标准>>> 最近用Django开发项目,在使用datetime类获取.now()时,获取的时间比实际时间相差8小时左右(感觉是UTC时间),服务器使用的时区是“Asia/Shanghai”(08…