更新 : 2007 年 11 月
Microsoft ASP.NET の Web ページは、複数のラウンド トリップにわたって、そのページ自身の状態を保持できます。コントロールにプロパティが設定されていると、ASP.NET はコントロールの状態の一部としてプロパティ値を保存します。アプリケーション側では、これによってページの有効期間が複数のクライアントの要求に渡って指定されます。このページ レベルの状態は、ページの ViewState と呼ばれます。
通常の ASP.NET Web ページでは、ViewState はフォームの隠しフィールドとしてサーバーによって送信されます。これはクライアントへの応答の一部として行われます。また、ViewState はクライアントからポストバックの一部としてサーバーに返されます。ただし、モバイル コントロールの使用時には、必要な帯域幅を減らすため、ASP.NET はページの ViewState をクライアントに送信しません。その代わり、ViewState はユーザーのセッションの一部としてサーバーに保存されます。ViewState がある場合は、このページの ViewState を認識する隠しフィールドが ASP.NET によってクライアントへの各応答の一部として送信され、クライアントによって次のポストバックの一部としてサーバーに返されます。
ViewState 履歴の管理
特定のページの ViewState はサーバーに保存する必要があるため、ユーザーがーブラウザの [戻る] ボタンをクリックすると、サーバーでの現在の状態がブラウザの現在のページと同期しなくなる可能性があります。たとえば、ユーザーがページ 1 に移動し、ボタンをクリックしてページ 2 に移動した後、[戻る] をクリックしてページ 1 に戻るとします。この場合、ブラウザの現在のページはページ 1 ですが、サーバーでの現在の状態はページ 2 です。
この問題に対処するため、ASP.NET モバイル Web ページは、ViewState 情報の履歴をユーザーのセッションの間保持します。クライアントに送信される各識別子は、この履歴内の位置に一致します。上の例で、ユーザーが再度ページ 1 からポストすると、モバイル Web ページはページ 1 に保存されている識別子を使用して ViewState 履歴と同期します。
この履歴のサイズは、アプリケーションに合わせて微調整できます。既定のサイズは 6 ですが、以下の例に示すように、数値属性を Web.config ファイルのタグに追加することによって変更できます。
<configuration>
<system.web>
<mobileControls sessionStateHistorySize="10" />
</system.web>
</configuration>
有効期限切れのセッションの管理
ViewState はユーザーのセッションの間保存されるため、セッションが有効な時間内にページがポストバックされないと ViewState の有効期限が切れることがあります。この有効期限は、モバイル Web ページに固有のものです。使用できる ViewState のないページをユーザーがポストバックすると、ページの OnViewStateExpire メソッドが呼び出されます。このメソッドの既定の実装では、ViewState の有効期限が切れていることを示す例外がスローされます。ただし、有効期限後に ViewState を手動で復元する機能がアプリケーションにある場合は、このメソッドをページ レベルでオーバーライドして、基本実装を呼び出さないようにできます。
ViewState の有効化および無効化
セッションを使用した ViewState の管理には、応答のサイズが小さくなるという利点があります。短所は、セッション状態を効率的に使用しないとパフォーマンスが低下することがあるという点です。大量のデータを含んだコントロールを使用する場合は、カスタム ページングや ViewState の無効化などの手法で効率を上げることができます。たとえば、ニュース記事を表示するサイトについて考えてみましょう。このようなサイトでは、記事の内容をユーザー セッションごとに保存する代わりに、各記事の 1 つのコピーだけをサーバーにキャッシュし、セッション状態の使用を最小限に抑えるような、データへの高度なアクセス方法を使用できます。
コントロールとその子の ViewState を無効にするには、コントロールの EnableViewState プロパティを false に設定します。ページ全体の ViewState を無効にするには、@ Page ディレクティブの EnableViewState 属性を false に設定します。
ViewState が無効になっているときでも、一部のモバイル コントロールはクライアントのラウンド トリップ間の重要なステータス情報を保存します。このような情報の例としては、ページの現在アクティブなフォームなどがあります。ViewState を無効にすると、ページは、ラウンド トリップ時にクライアントに送信される隠しフォーム変数として重要な情報を保存します。
Cookie およびクライアント状態の管理
既定では、ASP.NET のセッション管理機能はサーバーにセッションの Cookie をクライアントに書き込むように要求します。その後、クライアントはセッションの間に各要求の Cookie を送信し、サーバーは Cookie の情報を使用してセッション状態の情報を調べます。ただし、モバイル デバイスの多くは Cookie をサポートしていません。ViewState を含め、セッション管理がこのようなデバイスで正常に機能するには、Cookie なしのセッション管理を使用するようにアプリケーションを構成する必要があります。この機能を有効にすると、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. Simulate 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, {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. Normally, you would 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 の読み取りまたは書き込みを行うことができます。
メモ :
セキュリティ上のリスクを回避するため、セッション状態に重要な情報を含める場合は、HTTPS および SSL/TLS 認証を使用した接続を使用するようにしてください。