について
少しでも理解していれば、Asp.net ページの ViewState は通常、ページの非表示フィールドに保存されることがわかります:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value=" 乱雑なものの束">
ページのソース ファイルを参照すると、多くの乱雑なものが表示されます (特に、ページに大量のデータを含む DataGrid または ASP.NET 2.0 の GridView がある場合)。時間、つまり ViewState です。
基礎知識
ASP.NET 2.0ではViewStateの永続保存機構に新たな変更がいくつかあるので、関連するものを簡単に紹介します。
ASP.NET 1.1 では、ページの非表示ドメインの永続化メカニズムのみが提供されるため、DataGrid に数万のレコードがある場合は、場合によっては ViewState の使用を諦めなければなりません (考えないでください)。これは異常です) 必要はありません (誰かがこれに遭遇しました)。ViewState が有効になっている場合、IIS サーバーがそれに耐えられるかどうか、またネットワークがそれに耐えられるかどうかを確認してください。もちろん、Page.SavePageStateToPersistenceMedium() メソッドをオーバーライドすることでストレージ メカニズムを変更できますが、Page.LoadPageStateFromPersistenceMedium() はペアであるため、忘れずにオーバーライドしてください。
ASP.NET 2.0 のデフォルトのビューステート永続化メカニズムは、ページ上の非表示の HTML 要素 (type 属性が「hidden」に設定されている要素) に Base64 でエンコードされた文字列として状態情報を保持します。 ASP.NET ページは、HiddenFieldPageStatePersister オブジェクトを使用してこの作業を実行し、IStateFormatter インスタンスを使用してオブジェクトの状態情報をシリアル化および逆シリアル化します。または、帯域幅とリソースが制限されているモバイル クライアントの場合は、SessionPageStatePersister クラスを使用して、ページのビュー ステートをサーバー上の Session オブジェクトに保存することもできます。実際には、セッション永続化メカニズムはもう 1 つだけ保存しておきましょう。ページ内ではなくセッション内でページの状態を確認できるため、帯域幅が節約されます。
ただし、ViewState 永続化メカニズムをより深く理解したい場合は、抽象クラス PageStatePersister について知っておく必要があります。既存のビューステート永続化メカニズムをサポートできないクライアントでビューステートを保持するには、PageStatePersister クラスを拡張して、また、ページ アダプターを使用して、ページが提供されるクライアントの種類に基づいて、さまざまなビュー ステート永続メカニズムを使用するように ASP.NET アプリケーションを構成できます。 PageStatePersister クラスから派生したクラスは、Save 抽象メソッドをオーバーライドしてビュー ステートとコントロール ステートを永続メディアに保存し、Load メソッドをオーバーライドして状態情報を抽出する必要があります。ビュー ステートとコントロール ステートを文字列にシリアル化する必要がある場合は、StateFormatter プロパティを通じてアクセスされる IStateFormatter オブジェクトを使用できます。オブジェクトの状態情報を Base64 でエンコードされた文字列に効率的にシリアル化および逆シリアル化します。 StateFormatter プロパティをオーバーライドして、独自のオブジェクト状態シリアル化メカニズムを提供することもできます。これを行う方法は、非常に簡単です。
ViewState 永続化メカニズムの
隠しフィールド
は導入されません。これはデフォルトのフィールドです。序文に述べた通り。
セッションは
、ASP.NET2.0 の PageStatePersister プロパティをオーバーライドするだけで済みます。
protected オーバーライド PageStatePersister PageStatePersister
{
得る
{
新しいSessionPageStatePersister(Page)を返します;
}
ASP.NET1.1 の LoadPageStateFromPersistenceMedium のこれら 2 つのメソッドをオーバーライドする必要がある場合:
protected
override object LoadPageStateFromPersistenceMedium()
{
戻りセッション["ViewState"];
protected
オーバーライド void SavePageStateToPersistenceMedium(object viewState)
{
セッション["ビューステート"] = ビューステート;
RegisterHiddenField("__VIEWSTATE", "");
データベース
(私の例は SQL Server2000)
は、以下の紫色の行に注目してください。私は数日間落ち込んでいました。 。以下のコードは私のソースコードからコピーしたものです。必要な部分を除いて、このように記述する必要はありません。
protected オーバーライド void SavePageStateToPersistenceMedium(オブジェクト状態)
{
string viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
ClientScript.RegisterHiddenField("__VIEWSTATE","");//
試し
てみてください。
{
if (losFormatter == null)
{
losFormatter = 新しい LosFormatter();
}
StringWriter sw = 新しい StringWriter();
losFormatter.Serialize(sw, state);
Common.ViewStateData vsd = new ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = sw.ToString();
da = 新しい DataAccess();
文字列エラー = da.SaveViewState(vsd);
応答.書き込み(エラー);
}
catch (例外例)
{
Response.Write(例:メッセージ);
}
保護されたオーバーライド オブジェクト LoadPageStateFromPersistenceMedium(
)
{
文字列 viewState = string.Empty;
試す
{
if (losFormatter == null)
{
losFormatter = 新しい LosFormatter();
}
string stateID = Page.Request["__VIEWSTATE_KEY"].ToString();
da = 新しい DataAccess();
viewState = da.LoadViewState(状態ID);
}
キャッチ
{}
return losFormatter.Deserialize(viewState);
なぜ
これが基本的なのかという
と、この行があってもなくても同じです。 .net1.1 他の人のコードも参照してこの行を追加しました。この行を追加すると、ページに <input type="hidden" name="__VIEWSTATE" value="" /> が追加されるだけです
。実行後のページのソースファイルにはそのようなものが2つあります
。
その行は削除しても大丈夫なので、何に使用されているのか分かりません。明確に教えてください。しかし、Asp.net2.0 では機能しません。「
このページの状態情報は無効であるため、壊れている可能性が
あります。」というエラーが表示されます。とにかく、このようなエラーに遭遇したことはありませんでした。 Googleで検索しても何も見つかりません、はい、その文が間違っているかどうかはわかりませんが、私は自然にそのプロセス全体を追跡しています。ビューステートをデータベースに保存してデータベースから読み取ると、エラーが見つからなかったので、コードを何度も考えましたが、なぜページが非表示を登録する必要があるのか少し混乱しました。 「__VIEWSTATE」フィールドなので、この行をコメントアウトしましたが、実際には機能しました。そのため、この行が何のためにあるのかまだ理解していません。
もちろん、ASP.NET2.0 の新機能である PageStatePersister の新しいサブクラスを作成して、上記の関数を完成させることもできます:
名前空間 PageAdapter
{
システムを使用する;
System.IO を使用します。
System.Security.Permissions を使用します。
System.Web を使用します。
System.Web.UI を使用;
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
パブリック クラス DatabasePageStatePersister : PageStatePersister
{
public DatabasePageStatePersister(ページ ページ): ベース(ページ)
{}
//
// ViewState と ControlState をロードします。
//
パブリックオーバーライド void Load()
{
文字列ビューステート;
IStateFormatter フォーマッタ = this.StateFormatter;
DataAccess da = new DataAccess();
string stateID =base.Page.Request["__VIEWSTATE_KEY"].ToString();
viewState = da.LoadViewState(状態ID);
ペア statePair = (ペア)formatter.Deserialize(viewState);
ViewState = statePair.First;
ControlState = statePair.Second;
}
//
// ViewState と ControlState を永続化します。
//
パブリックオーバーライド void Save()
{
if (ViewState != null || ControlState != null)
{
if (Page.Session != null)
{
string viewStateID = "VIEWSTATE#" +base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
Base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
ペア statePair = 新しいペア(ViewState, ControlState);
IStateFormatter フォーマッタ = this.StateFormatter;
// statePair オブジェクトを文字列にシリアル化します。
string generatedState = formatter.Serialize(statePair);
ViewStateData vsd = new ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = シリアライズされた状態;
DataAccess da = new DataAccess();
文字列エラー = da.SaveViewState(vsd);
}
それ以外
throw new InvalidOperationException("StreamPageStatePersister にはセッションが必要です。");
}
}
次に
、
PageStatePersister プロパティをオーバーライドできます。
protected override PageStatePersister PageStatePersister
{
得る
{
新しい DatabasePageStatePersister(Page) を返します。
}
このファイルは
データベースとあまり変わりません。ASP.NET2.0 についてのみ話しています。ASP.NET1.1 でも同様であるはずですが、デバッグ用のコードは
まだ
書いていません。PageStatePersister の新しいサブクラスの作成:
名前空間 StreamPageAdapter
{
システムを使用する;
System.IO を使用します。
System.Security.Permissions を使用します。
System.Web を使用します。
System.Web.UI を使用します
。
// StreamPageStatePersister はビューステートの例です
// ビューとコントロールを永続化する永続化メカニズム
// Web サーバー上の状態。
//
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
public class StreamPageStatePersister : PageStatePersister
{
public StreamPageStatePersister(ページ ページ): ベース(ページ)
{}
//
// ViewState と ControlState をロードします。
//
パブリックオーバーライド void Load()
{
ストリーム stateStream = GetSecureStream();
// StateFormatter を使用して状態文字列を読み取ります。
StreamReader リーダー = 新しい StreamReader(stateStream);
IStateFormatter フォーマッタ = this.StateFormatter;
文字列 fileContents = Reader.ReadToEnd();
// Deserilize はシリアル化されたペア オブジェクトを返します。
// Save メソッド。
ペア statePair = (ペア)formatter.Deserialize(fileContents);
ViewState = statePair.First;
ControlState = statePair.Second;
Reader.Close();
stateStream.Close();
}
//
// ViewState と ControlState を永続化します。
//
パブリックオーバーライド void Save()
{
if (ViewState != null || ControlState != null)
{
if (Page.Session != null)
{
ストリーム stateStream = GetSecureStream();
StreamWriter ライター = new StreamWriter(stateStream);
IStateFormatter フォーマッタ = this.StateFormatter;
ペア statePair = newpai(ViewState, ControlState);
// statePair オブジェクトを文字列にシリアル化します。
文字列シリアル化状態 = formatter.Serialize(statePair);
Writer.Write(serializedState);
Writer.Close();
stateStream.Close();
}
それ以外
throw new InvalidOperationException("StreamPageStatePersister にはセッションが必要です。");
}
}
// 環境のプライベート ストリームを返します
GetSecureStream()
{
文字列パス = @"d:a.txt";
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
fs を返します。
}
}
PageStatePersister プロパティをオーバーライドするだけです。
protected
override PageStatePersister PageStatePersister
{
得る
{
新しい StreamPageStatePersister (ページ) を返します
。
上記の簡単な紹介を通じて、ある程度の理解が得られるはずですが、理解する必要があるのは、ASP.NET1.1 では、ASP 内で age.SavePageStateToPersistenceMedium() と Page.LoadPageStateFromPersistenceMedium() を書き換えることによってのみ上記の関数を完了できるということです。 .NET1.1 ASP.NET2.0 では、これに加えて、PageStatePersister の新しいサブクラスを作成し、PageStatePersister プロパティをオーバーライドすることで完成します。もちろん、次の内容を読んだ場合は違いは見つかりませんでした。実際に使用する PageStatePersister の新しいサブクラスを作成することがわかります。
ページ アダプターの使用 状態
永続メカニズムはアダプティブ レンダリングとクライアント側の機能に関連しているため、ASP.NET アプリケーションの DatabasePageStatePersister をアクティブにするために MyPageAdapter が提供されています。最後に、特定のクラスのクライアント (この場合はデフォルトの Web ブラウザ) に対して MyPageAdapter を有効にするために、ブラウザ機能 (.browser) ファイルが提供されます。
これらの内容については、私が提供したソース コードの PageAdapter プロジェクトを参照してください。読めばわかります。
System.Security.Permissions を使用します。
System.Web を使用します。
System.Web.UI
名前空間
を使用します。
{
[AspNetHostingPermission(SecurityAction.Demand, レベル = AspNetHostingPermissionLevel.Minimal)]
パブリック クラス MyPageAdapter : System.Web.UI.Adapters.PageAdapter
{
パブリック オーバーライド PageStatePersister GetStatePersister()
{
新しい PageAdapter.DatabasePageStatePersister(Page) を返します。
}
}
最後
に、MyPageAdapter アダプターを有効にするには、ASP.NET アプリケーションのルート ディレクトリに App_Browsers というディレクトリを作成し、構成情報を含む .browser ファイルを含める必要があります (実際、これらはすべて追加時に追加されます) .browser ファイルは、vs2005 までに自動的に完成します。構成ファイル内の <refID 要素は、Default.browser 構成ファイル内のデフォルトのブラウザによって指定された値を構成がオーバーライドすることを示します。この例では、ASP 用の MyPageAdapter を使用します。 .NET Web ページ (ただし、通常は
アダプターは
使用されません)。
<ブラウザrefID="デフォルト" >
<コントロールアダプター>
<アダプター
controlType="システム.Web.UI.ページ"
adapterType="PageAdapter.MyPageAdapter" />
</controlAdapters>
</ブラウザ>
</ブラウザ>
これは、ソース コードの TestPageAdapter プロジェクトで確認できます。このプロジェクトは、ページ アダプターのデモに使用されます。
結論
は比較的単純で、あまり明確ではないかもしれません。さまざまな永続化メカニズムの長所と短所については、特にテストしたわけではありません。最後の項目「ページ アダプターを使用する」は永続化メカニズムではありませんが、アダプターを使用します。
PageStatePersister 属性をオーバーライドしないようにします
。これは、PageStatePersister をオーバーライドするアクションをページの基本クラスに置くことができ、他のすべてのページがこの基本クラスを継承できるためです。私のコードではどうなっているのか、このページアダプターを使用するのは面倒です。もちろん、私はページアダプターについてあまり知りません。
さらに、ソース コードの簡単な説明:
1. PageAdapter プロジェクト
DatabasePageStatePersister.cs: PageStatePersister クラスのサブクラス MyPageAdapter.cs: ページ アダプター DataAccess.cs および ViewSate.cs データベース アクセス。補助クラスに属します。
2. StreamPageAdapter プロジェクトは
上記のものと似ているため、詳細は説明しません。
3. SaveStateToDatabase プロジェクト
StateInHiddenField.aspx: デフォルトのストレージ メカニズムをテストします。つまり、これを見ると、多くの厄介な点がわかります。ページのソース ファイル。
StateInSession.aspx: ストレージ メカニズムは Session です。
StateInDatabase.aspx: ストレージ メカニズム データベースは、asp.net1.1 および 2.0 で使用できるタイプです。
StateInDatabase2.aspx: PageStatePersister の新しいサブクラスを作成し、PageStatePersister プロパティをオーバーライドします。StateInFile.aspx
: ViewState をサーバー上のフォルダーに保存します。
4. TestPageAdater プロジェクト。
テストとアダプターに使用されます。