あの中には何が入ってる(保存されている)のでしょうか?
ViewStateに保存されるもの/されないものを理解してうまく付き合って行きましょう。
ViewStateの詳細は次の通りです。
まず、.NETを始めたばかりの人のために、ViewStateとは何ぞや?という話からしましょう。
ViewStateとは
複数のクライアントのラウンドトリップに渡って、そのページ自身の状態を保持するためのASP.NETの機能です。
いまいち良くわかりませんね。具体的な例をあげて説明しましょう。
ここでは説明だけですが、実際にページを作成してみるとわかりやすいでしょう。
例えば、画面上にラベルとボタンが1つずつ存在するページがあるとします。
このページのLoadイベントでは、PostBackでない場合のみ、ラベルに対して「ロードしました。」という文字列
をセットします。ボタンのClickイベントでは、何もしません。
このページをリクエストした場合、表示される画面には、先ほどセットした文字列とボタンが1つ表示されてい
ます。ここからが本番です。では、この状態で画面上のボタンをクリックしたらどうなるでしょうか。
先ほど言ったように、ボタンのClickイベントでは何もしません。(誤解のないように言っておきますが、クリッ
クによってポストバックはします。Clickイベントハンドラに何も記述しないという意味です)
実際にクリックしてみましょう。すると、どうでしょう。「ロードしました。」という文字列はラウンドトリッ
プ後も画面上に表示されています。
これが、ViewStateの機能です。
このようにページの状態を復元するためには、そのための情報をいずれかの場所に保持しておかなければなりま
せん。デフォルトでは、ViewStateはクライアントにページを送信する際、隠しフィールドとして画面自体に状態
情報を埋め込みます。
実際に表示された画面のソースを見てみると、formタグのすぐ下にinputタグがあり、このタグのname属性を見て
みるとname="__VIEWSTATE"となっているはずです。さらにvalue属性の値を見てみると、何やら暗号化された文字
列のようなものがあると思います。
これは、特に暗号化したデータではなく、単にbase64でエンコードされただけのデータです。
ポストバックが発生した時に、この隠しフィールドのデータを利用して状態を復元します。
誤解を恐れずに言うならば、「ViewStateとは、次にポストされてきたときに前に送信した内容を知るためのデ
ータ格納領域」と言えるでしょう。本当に誤解を恐れずに言うとこんなに簡単に表現できます。
しかし、誤解をされた方もいらっしゃるでしょうから、少し付け加えます。
前に送信した内容を知るためのデータを格納するとは言え、何から何まで格納しているわけではありません。
では、このViewStateにはどのようなデータが格納され、どのようなデータは格納されないのでしょうか。
ViewStateに格納されているもの・されていないもの
わかりやすい例として、テキストボックスを挙げてみたいと思います。
「ViewStateとは」で説明した画面にテキストボックスを2つとボタンを1つ追加したと想定してください。
そして、1つのテキストボックスには何らかのスタイルをデザイナで指定します(BackColorでもBorderColor
でも何でも良いです)。もう1つのテキストボックスはデフォルトのままにしておきましょう。
Loadイベントともとからあるボタンにイベント処理はそのままで良いです。
最後に追加したボタンのイベント処理を実装しましょう。
このイベント処理では、先ほど何も設定しなかったテキストボックスに何らかのスタイルを設定します。
これで準備ができました。ページを実行してみましょう。
まず、1つのテキストボックスにスタイルが設定されており、1つはデフォルトのままです。
では、スタイルを設定したテキストボックスに何らかの文字列を入力して、先ほど追加したボタンをクリックし
てみて下さい。
どうでしょう。
元々スタイルを設定したテキストボックスは、スタイルを維持したまま表示されてますね。
入力した文字列も表示されていると思います。
ボタンクリックイベントでスタイルを設定したテキストボックスはどうでしょう。
もちろん、スタイルが設定されて表示されていると思います。
さぁ、次です。
ではここで、最初からあるボタン(イベントハンドラに何も記述してないボタン)を押したらどうなるでしょうか。
答えは、「ボタンを押す前の状態とまったく同じ画面が表示される。」です。
重複になりますが、これがViewStateの機能です。
では、この画面上の情報のうち、どの情報がViewStateで管理されたものなのでしょうか。
すべてではありません。ViewStateはHTML自体にデータを埋め込むという性質上、必要最低限のデータしか保存
しないようにできています。必要のないものは保存されないのです。
説明をわかり易くするために、「では、さっきの画面では何が必要のない情報だったのか?」という観点で説明
しようと思います。
先ほどの画面で、ViewStateが管理していなかった情報を以下に列挙します。
・デザイナでスタイルを設定したテキストボックスのスタイル情報
・画面表示後、スタイル設定したテキストボックスに入力した文字列
先ほどの画面で、ViewStateが管理していた情報を以下に列挙します。
・ラベルにセットした文字列
・クリックイベントでスタイルを設定したテキストボックスのスタイル情報
※もちろんこれだけではありませんが、説明するにはこれだけ挙げておけば十分なので、あとは省略します。
デザイナでセットしたスタイル、テキストボックスの文字列はなぜViewStateに保存されなかったのでしょうか。
答えは簡単です。デザイナでセットしたスタイルは、デザイン時に生成されたコードに静的に記述されています。
つまり、ページのインスタンスが作成されるタイミングで毎回設定される事になります。よって、ラウンドトリ
ップ間でViewStateを利用しなくてもスタイルは設定されるのです。
テキストボックスの文字列はどうでしょうか。こちらは、わざわざViewStateに保存しなくても、サブミット時
に必ず送信されてきます。よってViewStateに保存する必要はありません。
逆に、ラベルにセットした文字列、イベントハンドラ内で設定したスタイルはインスタンス作成時には設定され
ませんし、送信もされません。よって、ViewStateによる管理が必要という事になります。
このように、ViewStateでは管理する情報と管理しなくても良い情報が切り分けられ、必要最低限のデータ量で
済むように考えられています。但し、設定した場所(デザイナ・コード)によってViewStateに保存されるかどう
かが決まるものもあります。先ほどのスタイルが良い例です。静的なスタイルなら、コードではなくデザイナや
スタイルシートを利用するべきなのは言うまでもありません。
非常に長くなってしまいましたが、あと後少しだけ。
説明で利用したサンプル画面で、本当に説明した通りになっているのかどうかを確認する方法があります。
ページのトレースを有効にして実行することです。
すると、ページ下部にトレース情報が表示されます。ここに「ViewStateサイズのバイト数」という情報が表示
されています。ここを確認すると、デザイナでスタイルを設定したテキストボックスは最初から最後まで、0
(ViewStateにデータは保存されていない事を表す)になっているはずです。
逆に、イベント内でスタイルを設定したテキストボックスは、スタイルを設定した直後から、このバイト数が
増えるはずです。
Tipsというよりは、コラムのようになってしまいましたが、これがどなたかの役に立っているとすれば、非常
に嬉しいことです。
※注
当ブログのTipsは、@IT等の情報サイトの内容を参考にして構成された記事
もあります。Tipsの内容に著作権等権利を侵害する内容があった場合には、
告知して下さい。早急に訂正または削除にて対応したいと思います。
ViewStateとは
複数のクライアントのラウンドトリップに渡って、そのページ自身の状態を保持するためのASP.NETの機能です。
いまいち良くわかりませんね。具体的な例をあげて説明しましょう。
ここでは説明だけですが、実際にページを作成してみるとわかりやすいでしょう。
例えば、画面上にラベルとボタンが1つずつ存在するページがあるとします。
このページのLoadイベントでは、PostBackでない場合のみ、ラベルに対して「ロードしました。」という文字列
をセットします。ボタンのClickイベントでは、何もしません。
このページをリクエストした場合、表示される画面には、先ほどセットした文字列とボタンが1つ表示されてい
ます。ここからが本番です。では、この状態で画面上のボタンをクリックしたらどうなるでしょうか。
先ほど言ったように、ボタンのClickイベントでは何もしません。(誤解のないように言っておきますが、クリッ
クによってポストバックはします。Clickイベントハンドラに何も記述しないという意味です)
実際にクリックしてみましょう。すると、どうでしょう。「ロードしました。」という文字列はラウンドトリッ
プ後も画面上に表示されています。
これが、ViewStateの機能です。
このようにページの状態を復元するためには、そのための情報をいずれかの場所に保持しておかなければなりま
せん。デフォルトでは、ViewStateはクライアントにページを送信する際、隠しフィールドとして画面自体に状態
情報を埋め込みます。
実際に表示された画面のソースを見てみると、formタグのすぐ下にinputタグがあり、このタグのname属性を見て
みるとname="__VIEWSTATE"となっているはずです。さらにvalue属性の値を見てみると、何やら暗号化された文字
列のようなものがあると思います。
これは、特に暗号化したデータではなく、単にbase64でエンコードされただけのデータです。
ポストバックが発生した時に、この隠しフィールドのデータを利用して状態を復元します。
誤解を恐れずに言うならば、「ViewStateとは、次にポストされてきたときに前に送信した内容を知るためのデ
ータ格納領域」と言えるでしょう。本当に誤解を恐れずに言うとこんなに簡単に表現できます。
しかし、誤解をされた方もいらっしゃるでしょうから、少し付け加えます。
前に送信した内容を知るためのデータを格納するとは言え、何から何まで格納しているわけではありません。
では、このViewStateにはどのようなデータが格納され、どのようなデータは格納されないのでしょうか。
ViewStateに格納されているもの・されていないもの
わかりやすい例として、テキストボックスを挙げてみたいと思います。
「ViewStateとは」で説明した画面にテキストボックスを2つとボタンを1つ追加したと想定してください。
そして、1つのテキストボックスには何らかのスタイルをデザイナで指定します(BackColorでもBorderColor
でも何でも良いです)。もう1つのテキストボックスはデフォルトのままにしておきましょう。
Loadイベントともとからあるボタンにイベント処理はそのままで良いです。
最後に追加したボタンのイベント処理を実装しましょう。
このイベント処理では、先ほど何も設定しなかったテキストボックスに何らかのスタイルを設定します。
これで準備ができました。ページを実行してみましょう。
まず、1つのテキストボックスにスタイルが設定されており、1つはデフォルトのままです。
では、スタイルを設定したテキストボックスに何らかの文字列を入力して、先ほど追加したボタンをクリックし
てみて下さい。
どうでしょう。
元々スタイルを設定したテキストボックスは、スタイルを維持したまま表示されてますね。
入力した文字列も表示されていると思います。
ボタンクリックイベントでスタイルを設定したテキストボックスはどうでしょう。
もちろん、スタイルが設定されて表示されていると思います。
さぁ、次です。
ではここで、最初からあるボタン(イベントハンドラに何も記述してないボタン)を押したらどうなるでしょうか。
答えは、「ボタンを押す前の状態とまったく同じ画面が表示される。」です。
重複になりますが、これがViewStateの機能です。
では、この画面上の情報のうち、どの情報がViewStateで管理されたものなのでしょうか。
すべてではありません。ViewStateはHTML自体にデータを埋め込むという性質上、必要最低限のデータしか保存
しないようにできています。必要のないものは保存されないのです。
説明をわかり易くするために、「では、さっきの画面では何が必要のない情報だったのか?」という観点で説明
しようと思います。
先ほどの画面で、ViewStateが管理していなかった情報を以下に列挙します。
・デザイナでスタイルを設定したテキストボックスのスタイル情報
・画面表示後、スタイル設定したテキストボックスに入力した文字列
先ほどの画面で、ViewStateが管理していた情報を以下に列挙します。
・ラベルにセットした文字列
・クリックイベントでスタイルを設定したテキストボックスのスタイル情報
※もちろんこれだけではありませんが、説明するにはこれだけ挙げておけば十分なので、あとは省略します。
デザイナでセットしたスタイル、テキストボックスの文字列はなぜViewStateに保存されなかったのでしょうか。
答えは簡単です。デザイナでセットしたスタイルは、デザイン時に生成されたコードに静的に記述されています。
つまり、ページのインスタンスが作成されるタイミングで毎回設定される事になります。よって、ラウンドトリ
ップ間でViewStateを利用しなくてもスタイルは設定されるのです。
テキストボックスの文字列はどうでしょうか。こちらは、わざわざViewStateに保存しなくても、サブミット時
に必ず送信されてきます。よってViewStateに保存する必要はありません。
逆に、ラベルにセットした文字列、イベントハンドラ内で設定したスタイルはインスタンス作成時には設定され
ませんし、送信もされません。よって、ViewStateによる管理が必要という事になります。
このように、ViewStateでは管理する情報と管理しなくても良い情報が切り分けられ、必要最低限のデータ量で
済むように考えられています。但し、設定した場所(デザイナ・コード)によってViewStateに保存されるかどう
かが決まるものもあります。先ほどのスタイルが良い例です。静的なスタイルなら、コードではなくデザイナや
スタイルシートを利用するべきなのは言うまでもありません。
非常に長くなってしまいましたが、あと後少しだけ。
説明で利用したサンプル画面で、本当に説明した通りになっているのかどうかを確認する方法があります。
ページのトレースを有効にして実行することです。
すると、ページ下部にトレース情報が表示されます。ここに「ViewStateサイズのバイト数」という情報が表示
されています。ここを確認すると、デザイナでスタイルを設定したテキストボックスは最初から最後まで、0
(ViewStateにデータは保存されていない事を表す)になっているはずです。
逆に、イベント内でスタイルを設定したテキストボックスは、スタイルを設定した直後から、このバイト数が
増えるはずです。
Tipsというよりは、コラムのようになってしまいましたが、これがどなたかの役に立っているとすれば、非常
に嬉しいことです。
※注
当ブログのTipsは、@IT等の情報サイトの内容を参考にして構成された記事
もあります。Tipsの内容に著作権等権利を侵害する内容があった場合には、
告知して下さい。早急に訂正または削除にて対応したいと思います。