Asp.net控件开发学习笔记(十)----服务器控件生命周期

简介:
在每一次http的Request和Response周期asp.net web form都会执行一系列被称为控件生命周期的预定义过程



    
    在第一次通过HTTP Get方法获取到页面后,每一次向服务端进行HTTP POST回传都会分为以下几个步骤:

1.      初始化控件树
2.       将回传的ViewState进行解析
3.      根据前几次的回传解析来为控件树中的每一个控件设置状态
4.      处理回传数据
5.      处理Page_Load事件
6.      通过PostBack通知控件的数据变化,并在必要的情况下更新控件状态
7.      执行基于控件状态改变的服务端事件(比如button的点击)
8.      将控件状态持久化为ViewState
9.      按照次序Render控件树中的每一个控件
10. Dispose整个页面和控件树
 

   由上面的列表可以看出整个的用户Request和服务器Response的周期,首先是将状态解析并根据控件的状态来处理状态的改变,最后处理完后将这些Render回客户端,并将新的状态以ViewState的形式保存在客户端的hidden form中。

 

 

  页面生命周期对应事件

  在页面生命周期中,上面所说的每一个步骤都有一个对应的事件。这也就意味着你可以通过Override事件的执行方法来在页面周期中插入你自己的实现

  

服务端事件

页面生命周期

描述

Init

Initialization

初始化控件树

LoadViewState

Unpack ViewState

从ViewState里提取出状态信息

LoadControlState

Unpack control state

从控件状态中提取出状态信息

LoadPostData

Handle form postback

从PostBack信息中更新控件状态信息

Load

Page_Load event

执行Page_Load内的事件

TrackViewState

Track ViewState

 

RaisePostDataChangedEvent

Initialization for

server-side events

通知控件回传的状态将改变其值

RaisePostBackEvent

Execute server-side events

对于指定的控件,如果状态信息改变,则引发该事件

PreRender

Render process

让每个空间接收最新的状态信息

SaveViewState

Save ViewState

保存ViewState

SaveControlState

Save control state

 

Render

Render process

Render标准HTML,Render的HTML带有控件的状态信息

Dispose

Dispose of control tree

释放资源

 

服务器生命周期和HTTP GET以及HTTP POST

   在System.Web.UI.Control基类定义了OnInit, OnLoad, OnPreRender, OnUnload,这四个事件可以被重写。而对于Dispose事件虽然Control也有定义,但并没有相应的OnDispose方法来引发事件,如果需要Dispose事件,需要实现IDispose接口。

   在通常情况下,第一次访问aspx页面时通过HTTP GET方法,而第二次以后都会通过HTTP POST方法,而HTTP POST方式进行访问服务器时,所需要经历的过程要比GET方式多,因为它包含了数据回传处理,下面是示意图:

   

 

   下面通过一个小Demo来查看控件的生命周期:

Demo Post回传生命周期

 

 首先先写一个控件,对每个控件的上述事件进行覆盖,最后通过在页面Trace来查看

 

   首先是控件的代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

 

namespace Life

{

    [ToolboxData("<{0}:lifecycle runat=server></{0}:lifecycle>")]

    public class Lifecycle : Control, IPostBackEventHandler, IPostBackDataHandler

    {

        protected override void OnInit(System.EventArgs e)

        {

            Trace("Lifecycle: Init Event.");

            base.OnInit(e);

        }

        protected override void TrackViewState()

        {

            Trace("Lifecycle: Track ViewState.");

            base.TrackViewState();

        }

        protected override void LoadViewState(object savedState)

        {

            Trace("Lifecycle: Load ViewState Event.");

            base.LoadViewState(savedState);

        }

        protected override void LoadControlState(object savedState)

        {

            Trace("Lifecycle: Load ControlState Event.");

            base.LoadControlState(savedState);

        }

        public override void DataBind()

        {

            Trace("Lifecycle: DataBind Event.");

            base.DataBind();

        }

        public bool LoadPostData(string postDataKey,NameValueCollection postCollection)

        {

            Trace("Lifecycle: Load PostBack Data Event.");

            Page.RegisterRequiresRaiseEvent(this);

            return true;

        }

        protected override void OnLoad(System.EventArgs e)

        {

            Trace("Lifecycle: Load Event.");

            base.OnLoad(e);

        }

        public void RaisePostDataChangedEvent()

        {

            Trace("Lifecycle: Post Data Changed Event.");

        }

        public void RaisePostBackEvent(string argument)

        {

            Trace("Lifecycle: PostBack Event.");

        }

        protected override void OnPreRender(System.EventArgs e)

        {

            Trace("Lifecycle: PreRender Event.");

            Page.RegisterRequiresPostBack(this);

            base.OnPreRender(e);

        }

        protected override object SaveViewState()

        {

            Trace("Lifecycle: Save ViewState.");

            return base.SaveViewState();

        }

        protected override object SaveControlState()

        {

            Trace("Lifecycle: Save ControlState.");

            return base.SaveControlState();

        }

        protected override void Render(HtmlTextWriter writer)

        {

            base.Render(writer);

            Trace("Lifecycle: Render Event.");

            writer.Write("<h3>LifeCycle Control</h3>");

        }

        protected override void OnUnload(System.EventArgs e)

        {

            Trace("Lifecycle: Unload Event.");

            base.OnUnload(e);

        }

        public override void Dispose()

        {

            Trace("Lifecycle: Dispose Event.");

            base.Dispose();

        }

        private void Trace(string info)

        {

            if (Context != null)

            {

                Context.Trace.Warn(info);

               System.Diagnostics.Debug.WriteLine(info);

            }

        }

    }

}

首先通过设置私有的Trace方法将Trace信息添加进页面当中,通过实现了IPostBackEventHandler和IPostBackDataHandler接口来实现Post方式回传所需要的几个方法。

 控件在前台的代码如下:

 首先在前台将Trace属性设置成True,其次注册控件

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default10.aspx.cs" Inherits="Default10" Trace="true" %>

<%@ Register Namespace="Life" TagPrefix="lc" %>

 

然后将控件放在页面内:

<lc:Lifecycle runat="server"></lc:Lifecycle>

输出结果如下:

  


   可以看出,我们对事件的实现都已经插入页面的生命周期内.



本文转自CareySon博客园博客,原文链接:http://www.cnblogs.com/CareySon/archive/2009/10/15/1584106.html,如需转载请自行联系原作者
相关文章
|
开发框架 JavaScript 前端开发
震撼!破解 ASP.NET 服务器控件 Button 执行顺序之谜,颠覆你的开发认知!
【8月更文挑战第16天】在ASP.NET开发中,通过Button控件实现先执行JavaScript再触后台处理的需求十分常见。例如,在用户点击按钮前需前端验证或提示,确保操作无误后再传递数据至后台深度处理。此过程可通过设置Button的`OnClientClick`属性调用自定义JavaScript函数完成验证;若验证通过,则继续触发后台事件。此外,结合jQuery也能达到相同效果,利用`__doPostBack`手动触发服务器端事件。这种方式增强了应用的交互性和用户体验。
248 8
|
10月前
|
存储 缓存
.NET 6中Startup.cs文件注入本地缓存策略与服务生命周期管理实践:AddTransient, AddScoped, AddSingleton。
记住,选择正确的服务生命周期并妥善管理它们是至关重要的,因为它们直接影响你的应用程序的性能和行为。就像一个成功的建筑工地,工具箱如果整理得当,工具选择和使用得当,工地的整体效率将会大大提高。
343 0
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
400 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
网络协议 Unix Linux
一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
328 4
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
1389 1
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
开发者 Windows
.NET 开源扁平化、美观的 C/S 控件库
【10月更文挑战第23天】介绍了三款适用于 .NET 平台的开源扁平化、美观的 C/S 控件库:MaterialSkin 采用 Google Material Design 风格,适合现代感界面;Krypton Toolkit 提供丰富控件,界面易于定制;Fluent Ribbon Control Suite 模仿 Office 界面,适合复杂功能应用。每款控件库均附有示例代码及 GitHub 链接。
817 0
|
C# Android开发 iOS开发
一组.NET MAUI绘制的开源控件 - AlohaKit
一组.NET MAUI绘制的开源控件 - AlohaKit
340 0
|
6月前
|
弹性计算 运维 安全
阿里云轻量应用服务器与云服务器ECS啥区别?新手帮助教程
阿里云轻量应用服务器适合个人开发者搭建博客、测试环境等低流量场景,操作简单、成本低;ECS适用于企业级高负载业务,功能强大、灵活可扩展。二者在性能、网络、镜像及运维管理上差异显著,用户应根据实际需求选择。
476 10