ViewState の情報を Session に保存する方法

概要

ViewState は、サーバ側のリソースを利用しないという利点があります。しかし、 GridView (または DataGrid) を使用する ViewState が非常に大きくなる場合があり、ネットワーク帯域が少ない環境でパフォーマンスが悪化します。

この記事では、 ViewState の情報を Session に保存する方法を紹介します。ただし、基本的には ViewState を使用する (そして、 ViewState のサイズを小さく保つ) のをおすすめします。

サイト全体で対応する方法

Web アプリケーションの失敗例: サイトの動きをスムーズに保つために気を付けたい ASP.NET の注意点トップ 10 -- MSDN Magazine, 2006 年 7 月 が参考になります。

基本的なステップは、以下の 2 ステップと非常に簡単です。

  1. カスタムページアダプタを作成
  2. 作成したカスタムページアダプタを既定のページアダプタに設定

カスタムページアダプタは、以下のように定義します。 GetStatePersister() をオーバーライドし、 SessionPageStatePersister クラスを返すようにします。

public class SessionPageStateAdapter :
    System.Web.UI.Adapters.PageAdapter
{
    public override PageStatePersister GetStatePersister ()
    {
        return new SessionPageStatePersister(this.Page);
    }
}

次に、 App_Browsers フォルダ *1 の中に .browsers ファイルを作成してください。既定のページアダプタに SessionPageStateAdapter を指定するため、以下のように controlAdapters 要素を記述します。

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.Page"
        adapterType="SessionPageStateAdapter" />
    </controlAdapters>
  </browser>
</browsers>

ページ単位に対応する方法

前述の Web アプリケーションの失敗例: サイトの動きをスムーズに保つために気を付けたい ASP.NET の注意点トップ 10 -- MSDN Magazine, 2006 年 7 月@IT:.NETエンタープライズWebアプリケーション開発技術大全 Webアプリケーションの状態管理が参考になります。

以下のように、 Page クラスの LoadPageStateFromPersistenceMedium() と SavePageStateToPersistenceMedium() をオーバーライドし、 Session に保存するようにします。

protected override object LoadPageStateFromPersistenceMedium ()
{
    string key = Request.RawUrl + "_VIEWSTATE";
    object state = Session[key];               
    return (state == null) ?
        base.LoadPageStateFromPersistenceMedium () : state;
}

protected override void
    SavePageStateToPersistenceMedium (object viewState)
{
    string key = Request.RawUrl + "_VIEWSTATE";
    Session[key] = viewState;
}

*1:存在しなければ作成してください。 App_Browsers フォルダは、 App_Code と同様に ASP.NET の特殊フォルダです。