次の方法で共有


ViewState の制御

Microsoft ASP.NET の Web フォーム ページは、複数のクライアントのラウンド トリップに渡って、そのページ自身の状態を保持することができます。コントロールにプロパティが設定されていると、ASP.NET はコントロールの状態の一部としてプロパティ値を保存します。アプリケーション側では、これによってページの有効期間が複数のクライアントの要求に渡って指定されます。このページ レベルの状態は、ページの ViewState と呼ばれます。

通常の Web フォームでは、ViewState はフォームの隠し変数としてサーバーによって送信されます。これはクライアントへの各応答の一部として行われます。また、ViewState は、ポストバックの一部としてサーバーに返されます。ただし、モバイル コントロールの使用時には、必要な帯域幅を減らすため、ASP.NET はページの ViewState をクライアントに送信しません。その代わり、ViewState はユーザーのセッションの一部としてサーバーに保存されます。ViewState がある場合、このページの ViewState を認識する隠しフィールドは、サーバーによってクライアントへの各応答の一部として送信され、クライアントによって次の要求の一部としてサーバーに返されます。

ViewState 履歴の管理

特定のページの ViewState はサーバー上に保存されるため、ブラウザの「戻る」機能を使用して履歴をさかのぼる場合に、現在の状態がブラウザの現在のページと同期されないことがあります。

たとえば、ユーザーがページ 1 に移動し、ボタンをクリックしてページ 2 に移動した後、[戻る] をクリックしてページ 1 に戻るとします。この場合、ブラウザの現在のページはページ 1 ですが、サーバーでの現在の状態はページ 2 です。

ASP.NET モバイル Web フォームは、この問題を軽減するため、ViewState 情報の履歴をユーザーのセッションの間保持します。クライアントに送信される各識別子は、この履歴内の位置に一致します。上の例で、ユーザーが再度ページ 1 からポストすると、モバイル Web フォームはページ 1 に保存されている識別子を使用して履歴と同期します。

この履歴のサイズは開発者が設定することが可能で、アプリケーションに合わせて調整する必要があります。既定のサイズは 6 ですが、以下の例に示すように、数値属性を Web.config ファイルのタグに追加することによって変更できます。

<configuration>
   <system.web>
      <mobileControls sessionStateHistorySize="10" />
   </system.web>
</configuration>

有効期限が切れたセッションの処理

ViewState はユーザーのセッションの間保存されるため、セッションが有効な時間内にページがポストバックされないと ViewState の有効期限が切れることがあります。この有効期限は、モバイル Web フォームに固有のものです。使用できる ViewState のないページをユーザーがポストバックすると、ページの OnViewStateExpire メソッドが呼び出されます。このメソッドの既定の実装では、ViewState の有効期限が切れていることを示す例外がスローされます。ただし、有効期限後に ViewState を手動で復元する機能がアプリケーションにある場合、アプリケーションはこのメソッドをページ レベルでオーバーライドして、基本実装を呼び出さないように選択できます。

ViewState の有効化および無効化

セッションを使用して ViewState を管理する ASP.NET の長所は、応答のサイズが小さいことです。短所は、セッション状態を効率的に使用しないとパフォーマンスが低下することがあるという点です。開発者は、大量のデータと共にコントロールを使用するときに、カスタム ページングや ViewState の無効化などの方法を使用して、効率を向上できます。たとえば、ニュース記事を表示するサイトについて考えてみましょう。セッションの間、記事の内容をユーザーごとに保存する代わりに、このようなサイトでは各記事の 1 つのコピーだけをサーバーにキャッシュし、セッション状態の使用を最小限に抑えるような、データへの高度なアクセス方法を使用することができます。

コントロールとその子の ViewState を無効にするには、コントロールの EnableViewState プロパティを False に設定します。ページ全体の ViewState を無効にするには、属性 EnableViewState="false" をディレクティブ @Page に追加します。

ViewState が無効になっているときでも、一部のモバイル コントロールはクライアントのラウンド トリップ間の重要な状態情報を保存します。このような情報の例としては、ページの現在アクティブなフォームなどがあります。ViewState を無効にすると、ページは、ラウンド トリップ時にクライアントに送信される隠しフォーム変数として重要な情報を保存します。

既定では、ASP.NET のセッション管理機能はサーバーにセッションの Cookie をクライアントに書き出すように要求します。その後、クライアントはセッションの間に各要求の Cookie を送信し、サーバーはこの情報からセッション状態を調べます。しかし、多くのモバイル デバイスは Cookie をサポートしていません。ViewState を含め、セッション管理がこのようなデバイスで正常に機能するには、クッキーレス セッション管理を使用するようにアプリケーションを構成する必要があります。この機能を有効にすると、ASP.NET は自動的にセッション キーをアプリケーション URL に挿入します。

デバイスには、Cookie をサポートしていないものもあります。クライアントの状態を長期にわたって保持するため、アプリケーションは事前に入力された顧客番号を使用することができます。クライアントに Cookie 機能があるとは限らないので、アプリケーションはクライアントをブックマーク可能な代替ページに移動する必要があります。以下のサンプル コードは、このようなサイトの例を示しています。ユーザーがこの URL を参照すると、顧客 ID を入力するフォームが表示されます。このとき、アプリケーションはユーザーがブックマーク可能な代替 URL を表示します。

<%@ Page Inherits="System.Web.UI.MobileControls.MobilePage" Language="C#"
   EnableViewState="false" %>

<script runat="server" language="c#">

protected void Page_Load(Object sender, EventArgs e)
{
   String customerID = Request.QueryString["cid"];

   if (customerID != null)
   {
      // A customer ID was found. Here, you would normally look
      // up the customer's profile in a database. 
      // This code simulates such a lookup by converting the client ID
      // back to a user.

      int underscore = customerID.IndexOf('_');

      if (underscore != -1)
      {
         // If visiting the first time, prompt the user to bookmark.

         if (Session["FirstTime"] != null)
         {
            Session["FirstTime"] = null;
            WelcomeLabel.Text = String.Format("Welcome to the site, {0}", 
               customerID.Substring(0, underscore));
            ActiveForm = WelcomeForm;
         }
         else
         {
            ReturnLabel.Text = String.Format("Welcome back, {0}", 
               customerID.Substring(0, underscore));
            ActiveForm = ReturnForm;
         }
      }
   }
}

protected void LoginForm_OnSubmit(Object sender, EventArgs e)
{
   // Generate a customer ID. Here, you would normally create
   // a new customer profile.

   String customerID = CustomerName.Text + "_" + 
      System.Guid.NewGuid().ToString();
   String path = AbsoluteFilePath + "?cid=" + 
      Server.UrlEncode(customerID);
   Session["FirstTime"] = true;
   RedirectToMobilePage(path);
}

</script>

<mobile:Form runat="server">
   <mobile:Label runat="server" StyleReference="title">
      Welcome to the site. Please register to continue.
   </mobile:Label>
   <mobile:TextBox runat="server" id="CustomerName" />
   <mobile:Command runat="server" OnClick="LoginForm_OnSubmit" 
      Text="Register" />
</mobile:Form>

<mobile:Form id="WelcomeForm" runat="server">
   <mobile:Label runat="server" id="WelcomeLabel" />
   Please bookmark this page for future access.
</mobile:Form>

<mobile:Form id="ReturnForm" runat="server">
   <mobile:Label runat="server" id="ReturnLabel" />
</mobile:Form>

モバイル アプリケーションの ViewState の最適化

モバイル Web フォーム ページでは、以下の事項を考慮することが重要です。

  • セッションの ViewState の保存は、高度に最適化されています。保存する ViewState がない場合は、セッションの間は何も格納されず、クライアントには識別子も送信されません。ただし、セッション管理を使用したくない、またはページのスループットを高くしたいと考えているアプリケーションの開発者は、ViewState の使用回数を減らすか、使用しない方法を検討してみてもかまいません。アプリケーションでは、多くの場合 (書式設定テキストのページのレンダリングなど) ViewState は不要であり、無効にするのが最適です。
  • モバイル Web フォーム ページは、アプリケーションの ViewState 以外に、ページに関する他の種類の状態情報を格納する必要があります。この情報には、アクティブなフォームや、フォームの改ページ情報などがあります。このような情報は、サーバーに保存されるのではなく、常にクライアントに送信され、ほとんどの場合は最適化された方法で生成されます。たとえば、最初のフォームがアクティブになるか、フォームの最初のページが表示される場合は、既定の状態が存在するため、この情報は保存されません。このような状態情報は、プライベート ViewState と呼ばれます。すべてのコントロールは、LoadPrivateViewState および SavePrivateViewState メソッドをオーバーライドしてプライベート ViewState の読み取りまたは書き込みを行うことができます。

隠し変数の詳細、および隠し変数を使用して ViewState 情報を保存する方法については、「ASP.NET の状態管理」を参照してください。

メモ   セキュリティ上のリスクを回避するため、セッション状態に重要な情報を含める場合は、HTTPS および SSL/TLS 認証を使用した、セキュリティで保護された接続を使用するようにしてください。

参照

セッション状態の管理 | ViewState のサポート | ASP.NET モバイル Web アプリケーションの作成 | アプリケーション開発者ガイド | モバイル Web アプリケーションの作成 | ASP.NET の状態管理 | LoadPrivateViewState | SavePrivateViewState