ViewState机制由浅入深2
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对象中。下面我们来看看它是如何存储的。
图3
图3是对Pair的一种图式表示方式,左边表示First对象,右边表示Second对象,根据这种图式方式,图4是利用Pair对象存储ViewState的结构,对于ControlState没有进行具体的展开。从savedState(Pair)开始采用了递归的存储方式,将所有控件的ViewState及关系存储起来,在Pair对象的First中存储ViewState数据,在Second中存储子控件的信息。
图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();

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











HTTP ステータス コード 520 は、サーバーがリクエストの処理中に不明なエラーに遭遇し、より具体的な情報を提供できないことを意味します。サーバーがリクエストを処理しているときに不明なエラーが発生したことを示すために使用されます。サーバー構成の問題、ネットワークの問題、またはその他の不明な理由が原因である可能性があります。これは通常、サーバー構成の問題、ネットワークの問題、サーバーの過負荷、またはコーディング エラーが原因で発生します。ステータス コード 520 エラーが発生した場合は、Web サイト管理者またはテクニカル サポート チームに連絡して詳細情報と支援を得ることが最善です。

HTTP 301 ステータス コードの意味を理解する: Web ページ リダイレクトの一般的なアプリケーション シナリオ インターネットの急速な発展に伴い、Web ページの操作に対する人々の要求はますます高くなっています。 Web デザインの分野では、Web ページのリダイレクトは一般的かつ重要なテクノロジであり、HTTP 301 ステータス コードによって実装されます。この記事では、HTTP 301 ステータス コードの意味と、Web ページ リダイレクトにおける一般的なアプリケーション シナリオについて説明します。 HTTP301 ステータス コードは、永続的なリダイレクト (PermanentRedirect) を指します。サーバーがクライアントのメッセージを受信すると、

解決策: 1. リクエスト ヘッダーの Content-Type を確認する; 2. リクエスト本文のデータ形式を確認する; 3. 適切なエンコード形式を使用する; 4. 適切なリクエスト メソッドを使用する; 5. サーバー側のサポートを確認する。

C# におけるネットワーク通信とセキュリティの一般的な問題と解決策 今日のインターネット時代では、ネットワーク通信はソフトウェア開発に不可欠な部分となっています。 C# では通常、データ送信のセキュリティ、ネットワーク接続の安定性など、ネットワーク通信の問題が発生します。この記事では、C# における一般的なネットワーク通信とセキュリティの問題について詳しく説明し、対応する解決策とコード例を提供します。 1. ネットワーク通信の問題 ネットワーク接続の中断: ネットワーク通信プロセス中に、ネットワーク接続が中断される場合があります。

C++ で HTTP ストリーミングを実装するにはどうすればよいですか? Boost.Asio と asiohttps クライアント ライブラリを使用して、SSL ストリーム ソケットを作成します。サーバーに接続し、HTTP リクエストを送信します。 HTTP 応答ヘッダーを受信して出力します。 HTTP 応答本文を受信して出力します。

HTTP ステータス コード 200: 成功した応答の意味と目的を調べる HTTP ステータス コードは、サーバーの応答のステータスを示すために使用される数値コードです。このうち、ステータス コード 200 は、リクエストがサーバーによって正常に処理されたことを示します。この記事では、HTTP ステータス コード 200 の具体的な意味と使用法について説明します。まず、HTTP ステータス コードの分類を理解しましょう。ステータス コードは、1xx、2xx、3xx、4xx、5xx の 5 つのカテゴリに分類されます。このうち、2xx は成功応答を示します。 200 は 2xx で最も一般的なステータス コードです

解決策: 1. 再試行: 一定時間待ってから再試行するか、ページを更新できます; 2. サーバーの負荷を確認します: サーバーの CPU、メモリ、およびディスクの使用状況を確認します。容量制限を超えている場合は、次のことを試してください。サーバー構成を最適化するか、サーバーの容量を増やします サーバー リソース; 3. サーバーのメンテナンスとアップグレードを確認します: サーバーが通常に戻るまで待つしかありません; 4. ネットワーク接続を確認します: ネットワーク接続が安定していることを確認し、ネットワークが正常に動作しているかどうかを確認しますデバイス、ファイアウォール、またはプロキシ設定が正しいことを確認します; 5. キャッシュまたは CDN 構成が正しいことを確認します; 6. サーバー管理者などに連絡します。

HTTP リクエストがタイムアウトになり、サーバーから 504GatewayTimeout ステータス コードが返されることがよくあります。このステータス コードは、サーバーがリクエストを実行しても、リクエストに必要なリソースを取得できないか、一定時間が経過してもリクエストの処理を完了できないことを示します。これは 5xx シリーズのステータス コードで、サーバーに一時的な問題または過負荷が発生し、その結果クライアントのリクエストを正しく処理できなくなったことを示します。 HTTP プロトコルでは、さまざまなステータス コードに特定の意味と用途があり、504 ステータス コードはリクエストのタイムアウトの問題を示すために使用されます。顧客の中で
