search
HomeDatabaseMysql TutorialViewState机制由浅入深2

ViewState机制由浅入深2

Jun 07, 2016 pm 03:48 PM
archivehttpviewstatemechanism

http://archive.cnblogs.com/a/1122213/ 2.2.2 Pair 类及ViewState的存储 Page 及所有控件的ViewState、ControlState都是存储在Pair类的实例中,了解Pair类及ViewState如何存储在Pair类中很重要。Pair定义的System.Web.UI中具体定义如下: public sealed cla

http://archive.cnblogs.com/a/1122213/


2.2.2   Pair类及ViewState的存储

Page及所有控件的ViewState、ControlState都是存储在Pair类的实例中,了解Pair类及ViewState如何存储在Pair类中很重要。Pair定义的System.Web.UI中具体定义如下:

public sealed class Pair

{

    public object First;

    public object Second;

    public Pair();

    public Pair(object x, object y);

}

可以看出Pair类是用作存储两个相关对象的基本结构。Pair是一个工具类,使用它很容易形成一个树的数据结构。将__VIEWSTATE反序列化后就是一个Pair对象。这个对象即保存了控件之间的父子关系,也保存了ViewState信息。ViewState中的Key/Value对被转换为一个ArrayList对象保存在Pair对象中。下面我们来看看它是如何存储的。

ViewState机制由浅入深2
图3

图3是对Pair的一种图式表示方式,左边表示First对象,右边表示Second对象,根据这种图式方式,图4是利用Pair对象存储ViewState的结构,对于ControlState没有进行具体的展开。从savedState(Pair)开始采用了递归的存储方式,将所有控件的ViewState及关系存储起来,在Pair对象的First中存储ViewState数据,在Second中存储子控件的信息。

ViewState机制由浅入深2图4

2.2.3   Control中的处理

Page类继承自Control类,在实现ViewState机制的时候Page类中主要是涉及序列化和反序列化的工作,ViewState的保存、装载等功能都在Control类中实现由Page类来继承,
控件也都继承自Control类,下面对Control类中和ViewState机制相关的属性、方法进行介绍。
<strong>1)<span>     </span>ViewState属性</strong>
ViewState是Page及控件的一个属性,这个属性并不是在Page或控件中定义,它定义在System.Web.UI.Control类中。它的声明如下:

protected virtual StateBag ViewState{get}

由于所有服务器端的控件,用户自定义控件,及Page类都是继承自Control类,所以它们都会都具有一个protected的ViewState属性。这个ViewState属性在ViewState机制中
很重要,它用来存储控件需要记忆的一些数据。这些数据主要有两类,一类是需要记忆的控件的属性。另外一类是我们想利用ViewState机制来记住的一些数据,
比如我们在Web窗体中写如下的代码:

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!this.IsPostBack)

        {

            this.ViewState["Test"] = 0;

        }

        else

        {

            this.ViewState["Test"]=int.Parse(this.ViewState["Test"].ToString()) + 1;

        }

<span>    }</span>
因为我们创建的Web窗体都是继承自Page类,所以在Web窗体中能否访问Page类的protected的ViewState属性。我们可以通过ViewState属性利用ViewState机制,让它帮助我们
记住一些信息。
ViewState属性的主要作用还是用来记住一些控件的属性值。ViewState属性和控件的其他属性有什么样的联系,才能够利用ViewState属性来记住他们呢?下面用Button类
的Text属性举例来说明,Text属性和ViewState属性是什么关系。Button.Text的定义如下:

public string Text

{

    get

    {

        string str = (string) this.ViewState["Text"];

        if (str != null)

        {

            return str;

        }

        return string.Empty;

<span>    }</span>

    set

    {

        this.ViewState["Text"] = value;

<span>    }</span>

}

通过上面的代码我们可以看出Button.Text属性的值实际上和ViewState中Key为“Text”的Value是关联的。当然Button类的其他属性也是类似的方式,
只是对应ViewState中Key不同而已。这样只要ViewState的值能够被记忆,那么Button类的属性也就能够被记忆住了。记忆ViewState的方法就是在Page. SaveAllState中
将所有控件的ViewState属性生成一个对象(这是一个特殊的对象,它是一个树状态的存储了所有控件的ViewState属性),然后将这个对象序列化为字符串,发送到客户端。
在下次请求的时候,将这个字符串发送给服务器,在Page.LoadAllState中将这个字符串反序列化为一个对象,将这个对象中存储的各个控件的ViewState属性,
加载给各个控件的ViewState属性。当我们访问控件的属性的时候就实现了对控件属性的记忆,之前设置的控件属性没有丢失。
<strong>2)<span>     </span>LoadViewStateByID属性</strong>

LoadViewStateByID的声明如下:

protected bool LoadViewStateByID{get}

LoadViewStateByID获取一个值,该值指示控件是否通过ID方式加载其视图状态。默认情况下是通过索引方式加载视图状态,索引方式是依赖子控件在父控件的Controls集合中位置。ID方式会根据ID查找控件,效率比较低些,但是有些情形必须使用这种方式比如延迟创建子控件时。

<strong>3)<span>     </span>EnableViewState属性</strong>
EnableViewState是一个bool类型的属性,来决定当前控件的ViewState机制是否可用。其声明如下:

public virtual bool EnableViewState{get,set}

<strong>4)<span>     </span>LoadViewStateRecursive</strong>
LoadViewStateRecursive的声明如下:
<span>internal</span><span>void</span><span> LoadViewStateRecursive(<span>object</span> savedState)</span>
Page.LoadAllState中调用Control.LoadViewStateRecursive,传入的参数savedState是一个Pair类型的对象,Pair.Fisrt中保存当前控件的ViewState,
Pair.Second中保存子控件的ViewState。对于EnableViewState为true时,先通过调用Control.LoadViewState(savedState.First)装载当前控件的ViewState。
之后根据LoadViewStateByID<span>属性,装载子控件的ViewState。</span>如果LoadViewStateByID<span>属性为true调用Control.</span>LoadChildViewStateByID(savedState.Second)<span>,否则调用</span>
<span>Control.</span>LoadChildViewStateByIndex(savedState.Second)。savedState.Second是一个ArrayList类型的对象。

Control.LoadViewState的声明如下:

<span>protected</span><span> <span>virtual</span> void LoadViewState(object savedState)</span>
在Control.LoadViewState中并没有自己实现装载当前控件的ViewState,而是通过ViewState.LoadViewState(savedState)来实现,下面会介绍StateBag的LoadViewState方法。
LoadChildViewStateByID<span>的声明如下:</span>
<span>internal</span><span> void LoadChildViewStateByID(<span>ArrayList</span> childState)</span>
参数childState是ArrayList类型,childState中存储了当前控件的所有子控件的信息。它的格式是首先是一个控件的ID,其后是这个控件的Pair对象。对childState进行循环
,循环中取得控件的ID,根据ID找到控件调用这个控件的LoadViewStateRecursive方法。示意代码如下:

for (int i = 0; i 2)

    {

        string id = (string) childState[i];

        object savedState = childState[i + 1];

       Control control = this.FindControl(id);

        control.LoadViewStateRecursive(savedState);

<span>    }</span>

<span>LoadChildViewStateByIndex</span><span>的声明如下:</span>

internal void LoadChildViewStateByIndex(ArrayList childState)

childState的存储格式是首先是一个控件的索引,其后是这个控件的Pair对象。根据索引访问访问这个控件,调用其LoadViewStateRecursive方法,示例代码如下:

    for (int i = 0; i 2)

    {

        int num4 = (int) childState[i];

        object savedState = childState[i + 1];

        controls[num4].LoadViewStateRecursive(savedState);

     }

<strong>5)<span>     </span>LoadViewState</strong>

LoadViewState中直接调用ViewState的LoadViewState方法进行ViewState的装载,示意代码如下:

this.ViewState.LoadViewState(savedState);

<strong>6)<span>     </span>SaveViewStateRecursive</strong>
SaveViewStateRecursive的声明如下:

internal object SaveViewStateRecursive()

对于EnableViewState为true时,先调用Control.SaveViewState返回一个包含当前控件的ViewState信息的ArrayList类型对象x。之后对子控件进行递归处理获得一个ArrayList类型的对象z。它的格式是ID(String),savedState(Pair)或者Index(int)savedState(Pair)。最后创建一个Pair对象Pair(x, z)。示意代码如下:

object x = this.SaveViewState();

ArrayList z = null;

ControlCollection controls = this._occasionalFields.Controls;

int count = controls.Count;

bool loadViewStateByID = this.LoadViewStateByID;

for (int i = 0; i

{

          Control control = controls[i];

          object obj4 = control.SaveViewStateRecursive();

          if (loadViewStateByID)

                    z.Add(control.ID);

          else

                              z.Add(i);

          z.Add(obj4);

}

return new Pair(x, z);

<strong>7)<span>     </span>SaveViewState</strong>

SaveViewState中直接调用ViewState的SaveViewState方法进行ViewState的保存,示意代码如下:

return this.ViewState.SaveViewState();

<strong>8)<span>     </span>TrackViewState</strong>

在Control.InitRecursive中会调用Control.TrackViewState,因为Control.InitRecursive是被递归调用的,所以每个控件的TrackViewState都会在初始化阶段被调用到。Control.TrackViewState中之间调用ViewState的TrackViewState方法,示意代码如下:

this.ViewState.TrackViewState();



Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
How does MySQL handle concurrency compared to other RDBMS?How does MySQL handle concurrency compared to other RDBMS?Apr 29, 2025 am 12:44 AM

MySQLhandlesconcurrencyusingamixofrow-levelandtable-levellocking,primarilythroughInnoDB'srow-levellocking.ComparedtootherRDBMS,MySQL'sapproachisefficientformanyusecasesbutmayfacechallengeswithdeadlocksandlacksadvancedfeatureslikePostgreSQL'sSerializa

How does MySQL handle transactions compared to other relational databases?How does MySQL handle transactions compared to other relational databases?Apr 29, 2025 am 12:37 AM

MySQLhandlestransactionseffectivelyusingtheInnoDBengine,supportingACIDpropertiessimilartoPostgreSQLandOracle.1)MySQLusesREPEATABLEREADasthedefaultisolationlevel,whichcanbeadjustedtoREADCOMMITTEDforhigh-trafficscenarios.2)Itoptimizesperformancewithabu

What are some best practices for writing efficient SQL queries in MySQL?What are some best practices for writing efficient SQL queries in MySQL?Apr 29, 2025 am 12:24 AM

Best practices include: 1) Understanding the data structure and MySQL processing methods, 2) Appropriate indexing, 3) Avoid SELECT*, 4) Using appropriate JOIN types, 5) Use subqueries with caution, 6) Analyzing queries with EXPLAIN, 7) Consider the impact of queries on server resources, 8) Maintain the database regularly. These practices can make MySQL queries not only fast, but also maintainability, scalability and resource efficiency.

How does MySQL differ from PostgreSQL?How does MySQL differ from PostgreSQL?Apr 29, 2025 am 12:23 AM

MySQLisbetterforspeedandsimplicity,suitableforwebapplications;PostgreSQLexcelsincomplexdatascenarioswithrobustfeatures.MySQLisidealforquickprojectsandread-heavytasks,whilePostgreSQLispreferredforapplicationsrequiringstrictdataintegrityandadvancedSQLf

How does MySQL handle data replication?How does MySQL handle data replication?Apr 28, 2025 am 12:25 AM

MySQL processes data replication through three modes: asynchronous, semi-synchronous and group replication. 1) Asynchronous replication performance is high but data may be lost. 2) Semi-synchronous replication improves data security but increases latency. 3) Group replication supports multi-master replication and failover, suitable for high availability requirements.

How can you use the EXPLAIN statement to analyze query performance?How can you use the EXPLAIN statement to analyze query performance?Apr 28, 2025 am 12:24 AM

The EXPLAIN statement can be used to analyze and improve SQL query performance. 1. Execute the EXPLAIN statement to view the query plan. 2. Analyze the output results, pay attention to access type, index usage and JOIN order. 3. Create or adjust indexes based on the analysis results, optimize JOIN operations, and avoid full table scanning to improve query efficiency.

How do you back up and restore a MySQL database?How do you back up and restore a MySQL database?Apr 28, 2025 am 12:23 AM

Using mysqldump for logical backup and MySQLEnterpriseBackup for hot backup are effective ways to back up MySQL databases. 1. Use mysqldump to back up the database: mysqldump-uroot-pmydatabase>mydatabase_backup.sql. 2. Use MySQLEnterpriseBackup for hot backup: mysqlbackup--user=root-password=password--backup-dir=/path/to/backupbackup. When recovering, use the corresponding life

What are some common causes of slow queries in MySQL?What are some common causes of slow queries in MySQL?Apr 28, 2025 am 12:18 AM

The main reasons for slow MySQL query include missing or improper use of indexes, query complexity, excessive data volume and insufficient hardware resources. Optimization suggestions include: 1. Create appropriate indexes; 2. Optimize query statements; 3. Use table partitioning technology; 4. Appropriately upgrade hardware.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software