第3回 ASP.NET開発の最初の壁:ポストバックとイベント・ハンドラ:VB6開発者のためのASP.NET開発入門(3/4 ページ)
ASP.NET開発に失敗する原因の1つは、ポストバックとイベントに対する理解不足。これらの仕組みを正しく理解しよう。
ポストバックを発生させないコントロールにおけるイベント処理
テキストボックスの入力内容を変更し、ボタンをクリックしたときのイベント処理は、どのように働いているのか? 先ほどのサンプル(1)を少し修正して、その動作を確かめてみよう。
●サンプル(2):テキストボックスの入力内容変更時のイベント処理の動作を確認する
サンプル(1)で作成したページに、TextBoxコントロール、Buttonコントロール、Labelコントロールを1つずつ貼り付ける。
また、各コントロールのプロパティを、下の表のように設定してほしい。
プロパティ | 値 | ||
---|---|---|---|
ボタン | (ID) | Button3 | |
Text | ボタン3 | ||
テキストボックス | (ID) | TextBox1 | |
ラベル | (ID) | Label2 | |
Text | (未入力) | ||
サンプル(2)の各コントロールのプロパティ値 それぞれの「(ID)プロパティ」は、デフォルトのままで変更していない。 |
テキストボックスの入力内容が変化したときに発生するのはTextChangedイベントであるため、TextBoxコントロールのTextChangedイベント・ハンドラを追加して(配置したTextBoxコントロールをダブルクリックすればよい)、そこに次の(太字の)コードを記述する。
……省略……
Protected Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Label2.Text = "テキストボックスの内容が変更されました"
End Sub
……省略……
Webフォームに貼り付けたTextBoxコントロールのTextChangedイベント・ハンドラに上記の(太字部分の)コードを記述する。
先に述べたとおり、テキストボックスの入力内容の変更時にはサーバへのリクエストは行われないので、ボタンがクリックされたときなどに発生するポストバック時に、初めてこのTextChangedイベント・ハンドラが実行され、Labelコントロールの表示が変化する。
実際に、ボタンがクリックされたときのリクエスト内容について見てみよう。
サンプル(2)実行時のWebブラウザ/Webサーバ間の通信内容
この画面の手順によりWebブラウザ/Webサーバ間の通信内容を確認する。Web Development Helperの使い方は先ほど示したのでここでは割愛する。
(1)テキストボックスに文字(この例では「テスト」)を入力する。
(2)[ボタン3]ボタンをクリックすると、ラベルに「テキストボックスの内容が変更されました」と表示される。
今度は、[Request Body]タブの[Name]の欄に「TextBox1」という(ID)名が、[Value]欄に「テスト」という値が表示されているため、テキストボックスに入力したデータがサーバに送られていることが確認できる。このように、TextBoxコントロールは(ポストバック時に)現在入力されている値をサーバに送るのである。
以上で、ポストバックが発生して始めてTextChangedイベントが発生することと、その際にテキストボックスに入力したデータがサーバに送信されていることが確認できた。
ここで、TextChangedイベントについてよく考えてみよう。このイベントは、「テキストボックスの内容が変更した」ときに発生するイベントであり、ポストバックが発生したときに常に発生するわけではない。ASP.NETはどうやってテキストが変更したことを知ることができたのであろうか?
この疑問に答える前に、WebアプリにおけるWebブラウザ/Webサーバ間の通信の特徴について知っておく必要がある。次に、これについて説明しておこう。
Webページが保持するメンバ変数のデータに関する注意点
以下では、先ほど作成したサンプル(2)にさらに機能を追加して、フォームのメンバ変数への代入を行うサンプルを作成する。
●サンプル(3):フォームのメンバ変数への代入を行う
サンプル(2)で作成したページに、Buttonコントロールを2つ、Labelコントロールを1つ貼り付ける。
また、各コントロールのプロパティを、下の表のように設定してほしい。
プロパティ | 値 | ||
---|---|---|---|
左のボタン | (ID) | Button4 | |
Text | 代入 | ||
左のボタン | (ID) | Button5 | |
Text | 取出し | ||
ラベル | (ID) | Label3 | |
Text | (未入力) | ||
サンプル(3)の各コントロールのプロパティ値 それぞれの「(ID)プロパティ」は、デフォルトのままで変更していない。 |
ページのメンバ変数として文字列型のstrDataを定義する(太字部分)。また、追加した各ButtonコントロールのClickイベント・ハンドラに、次の(太字の)コードを記述する。
……省略……
Private strData As String
Protected Sub Button4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button4.Click
strData = "ボタン4がクリックされました"
End Sub
Protected Sub Button5_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button5.Click
Label3.Text = strData
End Sub
……省略……
ページのメンバ変数として文字列型のstrDataを定義する(太字部分)。さらに、Webフォームに追加した各ButtonコントロールのClickイベント・ハンドラに、上記の(太字部分の)コードを記述する。
このコードでは、[代入]ボタン(Button4)のクリック時にフォームのメンバ変数(この例では「strData」)に文字列値を代入し、[取出し]ボタン(Button5)のクリック時にラベルにその文字列を表示する処理を実装している。
これを実際に動作させ、最初に[代入]ボタンをクリックし、続けて[取出し]ボタンをクリックすると何が起こるだろうか?
フォームのメンバ変数への代入を行うサンプル(3)の実行例
フォームのメンバ変数への代入を行うサンプル(3)を実際に動作させたところ。実行結果として、ラベルの表示が変更されないことに注目してほしい。
(1)[代入]ボタンのクリック時にフォームのメンバ変数に文字列を代入している。
(2)[取出し]ボタンのクリック時にフォームのメンバ変数に入っているデータを表示しようとしている。
VB6で同様のコードを書いた場合にはLabelコントロールに指定した文字列が表示されるはずだ。しかし、ASP.NETでは何も表示されないのだ。
ここで見ていただいたように、Webサーバ上で動くWebアプリでは、たとえページが持つ変数であっても格納したデータが保存されないのである。この仕組みは、ASP.NETに限らず、Webアプリの基本的な仕組みだ。
通常、Webアプリは多くのWebブラウザにさまざまなサービスを同時に提供しなければならない。このとき1台1台のクライアントのためにページの変数などの情報を保存しておくと、メモリなどの大量のリソースが必要となる。そこで、できるだけ少ないリソースで効率よくサービスを提供するために、このような仕組みを採っているのである。
これを踏まえて再び話を戻し、先ほどのテキストボックスの入力内容を変更したときのイベント処理の流れをもう少し深く考えてみよう。
Copyright© Digital Advantage Corp. All Rights Reserved.