SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント

ASP.NET Webフォームアプリケーションでの状態管理の使い分け

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント 第4回

状態管理のポイント

 今回は紙面の都合上、業務アプリケーション開発で使用することの多い、ViewState、Sessionについて注意すべきことを説明します。そのほかの方法や、より詳細な情報については、以下のページを参照してください。

Session

 Sessionは状態管理方法のうち最も使うものです。気軽に使用できる分乱用してしまいがちになりますが、使用する際には次のことに注意しましょう。

[1]あまりに巨大なデータは保存しない

 現在処理を行っているすべてのセッションがサーバーにデータを保存するため、あまりに巨大なデータを保存するとすぐにサーバーのリソース(メモリなど)が枯渇してしまいます。

 処理に必要な最低限のデータだけ保存するようにしましょう。

[2]不要になったらすぐにクリアする

 SessionはViewStateのように使い捨てではなく、セッションが続いている間ずっと値を保持し続けます。つまり使わない状態を残したままにすると、その分サーバーのリソースが無駄になってしまいます。

 不要になったらすぐにクリアするようにしましょう。クリアするにはキーを指定してnull(Visual BasicではNothing)を代入するか、Removeメソッドを使います。

リスト1 Sessionのクリア方法
Session["key"] = null;
Session.Remove("key");

[3]セッション状態モードのインプロセスは使用しない

 Sessionのデータ保存場所(セッション状態モード)には大きく分けて次の3つがあり、設定ファイル(Web.config)で設定できます。

  • インプロセス(既定)
    IISなどのWebサーバーのプロセスが持っているメモリ空間に保存する。
  • ステートサービス
    セッション状態を保存するための専用サービスに保存する。
  • データベース
    SQL ServerやOracleなどのデータベースに保存する。

 基本的に上の方からパフォーマンス高→低、耐障害性低→高となっています。

 これらはWeb.configのsessionState要素で切り替えることができますが、実運用環境では決して「インプロセス」にしてはいけません。

 これは、IISのプロセスは一定の時間で自動的に再起動されるようになっており、その際メモリ内に保存したSessionのデータが破棄されてしまうためです。また、さまざまな条件によって発生するアプリケーションの再起動によっても、同様に破棄されます。

 従って、最低でもステートサービスを使うようにし、あとは耐障害性やパフォーマンスの要件によって検討してください。

 詳しくは以下のページを参照してください。

ViewState

 ViewStateに設定されるデータは実際のところ、多くがサーバーコントロールによって自動的に設定されるものとなります。コードで状態を設定するケースは、個人的な感覚ではSessionに比べてあまり多くありません(その少ないケースの一つが、後で使用例として紹介する「ワンタイムトークン」です)。

 自動的に設定される状態、明示的に設定する状態がありますが、基本はなるべく使わないようにし、データ量を抑えるというのが第一です。具体的には次のことに注意するようにしましょう。

[1]ViewStateが不要なコントロールでは無効にする

 ViewStateにはサーバーコントロールによって、かなり大きなデータが自動で埋め込まれる場合があります。しかし、ViewStateによる状態保持が不要なケースも多く、コントロールごとにViewStateの有効、無効を制御することで、ViewStateのデータ量を減らせます。特に、ObjectDataSourceコントロールとデータバインドコントロールを組み合わせた場合、背後で自動的にSessionやデータベースなどから値を表示するようになるため、ViewStateは基本的に不要です。

 ViewStateの有効、無効を設定するにはPageや各コントロールのEnableViewStateプロパティ、ViewStateModeプロパティを使います。これらのプロパティの違いはというと、EnableViewStateプロパティは親コントロールの値が子コントロールには引き継がれませんが、ViewStateModeプロパティは引き継がれます。

 従って、Page.EnableViewStateプロパティをtrueにした上で、マスターページContentコントロールなどなるべく上位のコントロールのViewStateModeプロパティをDisabled、ViewStateを有効にしたいコントロールのViewStateModeプロパティをEnabledに設定する、といった方法を取ると良いでしょう。こうすることで、PageレベルのViewStateは有効、Pageに含まれるコントロール全体としては無効、必要なコントロールだけ有効、といった制御が可能になります。

 なお、Page.ViewStateModeプロパティをDisabledにしてしまうと、サーバー側でViewStateに設定したPageレベルの状態すら保存されなくなってしまいますので注意しましょう。

 もし興味があれば、サンプルアプリケーションのLocations.aspxにて、ContentコントロールのViewStateModeプロパティをDisabledからEnabledにして"__VIEWSTATE"項目のvalue属性の値がどう変化するか見てみてください。相当データ量に違いがあるはずです。

[2]あまり大きなデータを保存しない

 大きなデータをViewStateに保存すると、その分ネットワークにも負荷がかかりますし、ブラウザでの表示も遅くなる恐れがあります。

 従って、なるべく保存するデータ量を減らすため、基本的にViewStateではなくSessionを使うようにしましょう。ViewStateに設定する場合でも、ちょっとしたフラグや短い文字列程度の小さなデータにとどめておきましょう。

[3]機密性の高いデータを保存しない

 ViewStateに格納する値はBase64エンコーディングされ、パッと見暗号化されたように見えます。しかしBase64エンコードは暗号化ではなく、簡単にデコードが可能です。そのため、機密性の高いデータを保存してしまうと、簡単に情報が漏れてしまいます。

 従って、機密性の高いデータは原則としてViewStateではなくSessionに保存しましょう。どうしてもViewStateに保存したいという特殊な事情があるならば、System.Security.Cryptography名前空間に含まれる暗号化処理を行うクラス、例えばAesクラスやTripleDesクラスなどを使い、値を暗号化してから設定するようにしましょう。

次のページ
ViewState、Sessionを用いた多重送信防止

この記事は参考になりましたか?

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高野 将(タカノ ショウ)

<個人紹介>新潟県長岡市在住の在宅リモートワークプログラマー。家事や育児、仕事の合間に長岡IT開発者勉強会(NDS)、Niigata.NET、TDDBCなどのコミュニティに関わったり、Web記事や書籍などの執筆を行ったりしている。著書に『アプリを作ろう! Visual C#入門 Visual C# 2017対応』(日経BP社、2017)など。< WINGSプロジェクト について>有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での 登録メンバ は約50名で、現在も執筆メンバを 募集中 。興味のある方は、どしどし応募頂きたい。 著書 記事 多数。 RSS X: @WingsPro_info (公式)、 @WingsPro_info/wings (メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6622 2012/06/28 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー