Webアプリケーションにおいて、ブラウザ上で入力されたデータをサーバ側に送信することを「データをポストする」と表現することがある。これはHTTPプロトコルのPOSTメソッドからきた表現であると思われるが、ASP.NETでは「ポスト」とは別に「ポストバック」という新しい言葉が登場する。ポストバックはポストと何が違うのだろうか?
いま、Visual Studio .NETで「PostBack1」という名前の「ASP.NET Webページ」のプロジェクトを新規作成し、次のようにTextBoxコントロールとButtonコントロールをWebフォームに配置したとしよう。
こうしておいて、メニューの[ビルド]−[ソリューションのビルド]を実行し、アプリケーションをビルドする。ブラウザで次のURLを開けば、このWebアプリケーションを実行することができる。
http://localhost/PostBack1/WebForm1.aspx
この作業は、HTTPプロトコルのGETメソッドによりページを取得していることになる。
次に、こうして表示されたWebページのソース・コードを見てみよう。その中でも<form>要素部分は次のようになっているはずだ。
<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">
<input type="hidden" name="__VIEWSTATE" value="dDwxNDg5OTk……" />
<input name="TextBox1" type="text" id="TextBox1" />
<input type="submit" name="Button1" value="実行" id="Button1" />
</form>
Webフォームに配置したButtonコントロールはsubmitボタンとしてHTML文に置き換わっているのが分かる(3つ目の<input>タグ)。このボタンがクリックされると、<form>要素内の各コントロールの内容が、<form>タグのaction属性で指定されたページに対してサブミット(「提出」の意)される。
この場合にサブミットされる内容は、そこに記述されている隠しフィールドにより埋め込まれた値と、テキスト・ボックスで入力されている文字列値である。
すなわち、ボタンがクリックされることにより、action属性に記述されているページが呼び出され、その際にフォーム内のコントロールの値がサーバへ送信される。このような、フォームのサブミットによるデータの送信が「データをポストする」という処理だ。
さてここで注目すべきは、<form>タグのaction属性の内容である。
入力フォームを持った一般的なページでは、ここに入力データを処理し、その結果を表示するようなページのURLが記述される。つまり、結果処理ページにフォームの入力データをポストするわけだ。
しかしASP.NETでは、action属性に埋め込まれるURLは、上記のフォームのように常に現在開いているページのURLとなる。このため、ASP.NETにより生成されたページでは、データをポストする先は常にそのページ自身である。このようなポストを、ASP.NETでは特に「ポストバック」と呼んでいるのである。
Visual Studio .NETのデザイン画面に戻って、WebフォームのWebForm1.aspxをHTML表示させると、フォーム部分のスクリプトは次のようになっている。
<form id="Form1" method="post" runat="server">
<asp:TextBox id="TextBox1" runat="server"></asp:TextBox>
<asp:Button id="Button1" runat="server" Text="Button"></asp:Button>
</form>
この時点ではaction属性は作成されていない。しかし、「runat="server"」の付いた<form>タグでは、必ず自分自身を指したaction属性を含んだHTML文が生成されることになる。
ちなみに、method属性には「get」や「post」などの「サブミット時のメソッド」を記述するが、ASP.NETではここに「get」を指定してもポストバックは正しく行われる。
ポストバックの仕組みにより、ASP.NETではポストしたデータを処理するのは、常にそのページ自身となる。そのため、ASP.NETのページには基本的に入力フォーム部分と処理結果の表示部分が同居することになる*1。
多くのWindowsアプリケーションがこのような作りになっていることを思い出してほしい。ポストバックに加え、ビューステートなどによる自動状態管理、そしてイベント・ハンドラによるイベント処理などにより、ASP.NETはHTTPベースのWebアプリケーションにおいても、Windowsアプリケーションと同じプログラミング・モデルを実現しようとしていると考えることができるだろう。
逆に、自動状態管理やイベント駆動型のプログラミングを実現にするためには、ポストバックは必須の処理である(ビューステートによる自動状態管理については「TIPS:[ASP.NET]ビューステートに保存されるものは?」で解説している)。
*1ちなみに、処理結果の表示ページを別ページとしたい場合、ASP.NETでは、サーバ側でページを転送するのが一般的な手法である。これについては「プログラミングASP.NET:第16回 ASP.NETにおけるページの遷移」を参照していただきたい。
さて、このようにWindowsアプリケーションと同じプログラミング・モデルを採用しているASP.NETであるが、Windowsアプリケーションとは大きく異なるポイントが1つある。それはページ(Webフォーム)を初期化するタイミングであるLoadイベントが、ポストバック時も含めて毎回のページのアクセスで発生するということだ。
これは、Webページを処理するインスタンスが、ページがアクセスされるたびに新しく生成されるということに起因する。つまり、いまブラウザで表示しているHTML文を作成したインスタンスと、ポストバックにより次に表示されるHTML文を作成するインスタンスとは別物なのである(多数のユーザーが同時にアクセスするWebアプリケーションでは、ページのインスタンスを保持し続けることは現実的でない)。Windowsアプリケーションでいえば、ボタンがクリックされるたびにフォームが新しく作り直されるようなイメージだ。
アクセスごとに新しく作成されたインスタンスでは、ビューステートなどの状態管理機能によりフォーム上のコントロールの状態は自動的に復元されるが、当然ながらプログラマーがインスタンス内で作成した独自のデータまでは復元されない。そのためASP.NETでは、初期化のためのLoadイベントが、インスタンスが作成されるたびに発生するようになっているのである。
しかし、たいていのアプリケーションでは、最初のLoadイベントでの初期化と、ポストバックによるLoadイベント時の初期化では、必要となる処理の内容は異なる。
そこで、これらを区別するために各ページにはIsPostBackプロパティが用意されている。これにより、Loadイベント処理時には、そのアクセスが初めてのアクセスなのか、ポストバックによるアクセスなのかを判別することができる。
このプロパティを用いると、Loadイベントを処理するイベント・ハンドラ(通常はPage_Loadメソッド)での記述は次のようになる。
void Page_Load() {
// 毎回行う初期化処理
if (!IsPostBack) {
// 最初のアクセス時にのみ行う初期化処理
} else {
// ポストバック時にのみ行う初期化処理
}
}
状態管理機能による自動復元により、ポストバック時には、多くのコントロールでその状態を初期化する処理は不要となるが、それを余計に上書きしないようにするためにも、このようなIsPostBackプロパティによる処理の分岐は必要となる。
なお、IsPostBackプロパティは、正確にはPageクラス(System.Web.UI名前空間)のプロパティである。実際に実行されるページはPageクラスから派生したクラスのインスタンスであるため、Pageクラスから継承しているプロパティはそのページ内からアクセスすることができる。
カテゴリ:Webフォーム 処理対象:ポストバック
使用ライブラリ:Pageクラス(System.Web.UI名前空間)
関連TIPS:[ASP.NET]ビューステートに保存されるものは?
Copyright© Digital Advantage Corp. All Rights Reserved.