.NETエンタープライズ
Webアプリケーション開発技術大全

ポストバック処理

マイクロソフト コンサルティング本部 赤間 信幸
2004/06/17
Page1 Page2 Page3 Page4

2.3 ポストバックの動作に関して注意すべき点

 ここまでポストバックのコンセプトとそのランタイム動作を解説したが、実際のポストバックを用いたプログラム開発ではいくつか注意すべき点がある。

A. サーバ側ではポストバック時もPage_Load()メソッドが毎回呼び出される

 初回リクエスト、ポストバック時を問わず、毎回ページインスタンスが作り直されるため、常にPage_Load()メソッドが呼び出される。Page_Load()メソッド内において、初回リクエスト時とポストバック時のページ初期化の挙動を変えたい場合には、IsPostBackというプロパティを利用する。リスト6に、ASP.NET処理ブロックのサンプルコードを示す。

C#の場合

<%@ Page Language="C#" %>

<script runat="server">
  protected void Page_Load(object source, EventArgs e) {
    if (IsPostBack == false) {
      // ここに初回リクエストにおける画面初期化のコードを記述する
    } else {
      // ここにポストバック時における共通の処理コードを記述する
    }
  }
</script>
(以下略)
VB.NETの場合

<%@ Page Language="VB" %>

<script runat="server">
  Protected Sub Page_Load(ByVal source As Object, ByVal e As EventArgs)
    If (IsPostBack = False) Then
      ' ここに初回リクエストにおける画面初期化のコードを記述する
    Else
      ' ここにポストバック時における共通の処理コードを記述する
    End If
  End Sub
</script>
(以下略)
リスト6 ASP.NET処理ブロックのサンプルコード

B. ブラウザからのポストバックはボタン押下の際に一括して行われる

 通常のHTMLとWebブラウザでは、テキストボックス内の文字列の変更やドロップダウンリストからの項目選択だけではデータ送信が行われない。ボタン押下の際に一括してWebサーバにデータが送信される。

 しかし場合によってはアプリケーションの利便性を高めるために、データ変更時にも即時にポストバックを行いたいと考えることもある(例えばドロップダウンリストからの項目選択に応じて詳細データをデータベースから取得し、即時に表示したいような場合)。このような場合には当該WebコントロールのAutoPostBack属性にtrueを設定する。このようにするとボタン押下を待たずにポストバックが行われるようになる※9。リスト7の場合、テキストボックスを変更すると即座にWebサーバにポストバックが行われる。

※9 内部的にはWebコントロールからクライアントブラウザに対してDHTMLを含むHTMLが出力されることにより実現されている。このため、この機能が利用できるのはクライアントがDHTMLをサポートするブラウザである場合に限られる。
 
ASP.NETコード

(ページディレクティブ、ASP.NET処理ブロックは割愛)

<HTML><BODY>
  <FORM runat="server">
    <asp:TextBox runat="server" id="MyTextBox"
ontextchanged="MyTextBox_OnTextChanged" autopostback="true" />
    <asp:Button runat="server" id="MyButton" text="表示" onclick="MyButton_OnClick"
/>
    <HR>
    <asp:Label runat="server" id="MyLabel" />
  </FORM>
リスト7 Webサーバにポストバックが行われるサンプルコード

C. ブラウザ上での変更操作の順序を完全に再現することはできない

 ASP.NETフレームワークはViewStateと最新データの突合せを元にクライアントブラウザ上での操作をWebサーバ上で再現するように振舞うが、残念ながらクライアントブラウザ上での操作順序までをも完全に再現することはできない。例えば図8のようにテキストボックス3個とボタン1個が並んでいる場合、サーバへのポストバックはボタン押下の際にまとめて行われるため、どの順番でテキストボックスが変更されたのかをWebサーバ上で再現することができない。

図8 テキストボックスが変更された順番をWebサーバ上で再現することができない例

Webサーバ上での順序の再現は、以下の順序でイベントハンドラを呼び出すことに限られている。

  • 通常ポストバックを発生させないデータ変更系のイベントハンドラ
  • ポストバックを発生させるボタン押下系のイベントハンドラ

 このため、特に変更系イベントハンドラの記述する際には、呼び出し順序・操作順序に依存するようなイベントハンドラを実装してはならない。

2.4. ポストバックのここまでのまとめ

 ではここで改めて、ポストバック処理の詳細なランタイム動作についてまとめておこう。

・ ASP.NETフレームワークは、ViewStateを活用することにより、ブラウザ上での操作をWebサーバ上で再現するように振舞う。
  ・ ブラウザ上で行われた操作を解析し、対応するイベントハンドラを自動的に呼び出してくれる。
 
・ ASP.NETフレームワークは、スケーラビリティを確保するためにページインスタンスを毎回破棄する。
  ・ 初回リクエスト時とポストバック時に使われるインスタンスは別物になる。
  ・ このため、ページインスタンス上にデータ変数を用いてデータを残しておくことはできない。

3 ポストバックを利用したプログラム設計のスタイル

 ではここまでの前提知識を元にして、実際にポストバックを使ったプログラムの設計スタイルについて考えてみよう。ポストバックはHTTPプロトコル上に、スケーラビリティとプログラマビリティを両立させるように作り上げられたフレームワークであるため、少なからずクセのあるプログラミングを要求される。特に、従来のASPやJSPでの開発スタイルに慣れ親しんだ方々にとってはやや慣れが必要な側面もある。特に注意すべき点は以下の2つである。

  • UI画面(ユーザインタフェース)とサーバ側プログラム(.aspx)の対応関係
  • 画面遷移の方法

3.1 UI画面とサーバ側プログラムの対応関係

 ここまで解説してきたように、ポストバックの根本思想には「UI画面とサーバ側プログラムとを一対一に対応させる」というものがあり、これを守るようにプログラムを設計するのが第一のポイントとなる。図9はASP.NETのポストバックを利用した場合の設計の基本指針を表している。

 具体的には、以下のルールを守るように設計・実装する。

  • ボタンが押されたときのビジネスロジック処理は、ボタンと同じ.aspxファイル中のイベントハンドラの中に実装する。
  • その画面に関連するビジネスロジック処理が完全に終了してから、次の画面(.aspxファイル)を呼び出す。
図9 ASP.NETのポストバックを利用した場合の設計の基本指針

3.2 画面遷移の方法

 あるページでの処理が完全に終了したのちに次の画面に遷移するには、イベントハンドラの最後で移動先のページをResponse.Redirect命令により指定する(リスト8)。

C#の場合

<%@ Page Language="C#" %>

<script runat="server">
  protected void Page_Load(object source, EventArgs e) {
  }

  protected void MyButton_OnClick(object source, EventArgs e) {
    // ビジネス処理(データベースへの書き込みなど)を行ったのちに...
    Response.Redirect("NextPage.aspx");
 }
</script>
(後略)
VB.NETの場合

<%@ Page Language="VB" %>

<script runat="server">
  Protected Sub Page_Load(ByVal source As Object, ByVal e As EventArgs)
  End Sub

  Protected Sub MyButton_OnClick(ByVal source As object, ByVal e As EventArgs)
    ' ビジネス処理(データベースへの書き込みなど)を行ったのちに...
    Response.Redirect("NextPage.aspx")
  End Sub
</script>
(後略)
リスト8 Response.Redirect命令の使用例

 この命令は、クライアントブラウザに対してHTTP状態コード302を返すもので※10、ブラウザに対して次ページへの移動を指示するものである※11

※10 HTTP状態コードとは、Webサーバからクライアントブラウザに送り返される処理結果コードである。例えばページが存在しない場合には404、サーバ側プログラム内でエラーが発生した場合には500、正常終了した場合には200といったコードが返される。コード302は指定されたコンテンツが別の場所に一時的に移動したことを示すものであり、ほとんどのブラウザはこのコードを受け取ると指定された移動先へと自動的に遷移するように作られている。
 
※11 なお画面遷移にはResponse.Redirect命令とServer.Transfer命令の2つがあるが、ASP.NETフレームワークではResponse.Redirectを利用する(図10)。Server.Transferはクライアントへのラウンドトリップがない分パフォーマンスはよいが、ASP.NETランタイムの前段パイプライン処理がショートカットされ、HttpContext情報が再構築されないため、プログラミングモデルが複雑化する。最近はネットワークが高速化していることもあり、通常のLAN環境やブロードバンドのインターネット環境ではResponse.Redirect()命令によるラウンドトリップが性能面での致命的なボトルネックとなることはほとんど考えられない。なお、ASP.NETランタイムのパイプライン処理やHttpContext情報の詳細に関しては第3巻「ASP.NET応用編」を参照して頂きたい。

図10 Response.Redirect命令を使った場合の処理の流れ

 特に従来のASPやJSPでの開発に慣れ親しんでいる方々に気をつけて頂きたいのは、ASP.NETフレームワークでは、フォームの入力データは同一ページに対してしか送信できない(=ポストバックしかできない)ように設計されているという点である。従来のASPやJSPではFORMタグを自力で記述するため、入力データの送信先を任意のページに設定することが可能であった。しかしASP.NETフレームワークの場合、データ送信先はForm HTMLコントロールから自動的に出力され、かつその送信先は自ページ以外に変更することができないようになっている。

 このような設計になっているのは(本章の最初で解説した通り)ポストバックモデル(=送信先を常に自分自身のページにすること)が各種の設計問題を解決するためである。ASP.NETフレームワークはほぼすべての機能がこのポストバックモデルを前提としていることもあり、ポストバックとASP.NETフレームワークは切っても切り離せない関係になっている。

 ASP.NETアプリケーションフレームワークを利用せず、FORMタグをHTMLコントロール化しないで(runat="server"を付与しないで)ベタ書きすればデータ送信先を変更することは可能だが、それではASP.NETフレームワークのメリットを丸ごと捨てることになるため推奨できない。自ページにしか差し戻せないという振る舞いに戸惑いを感じるかもしれないが、是非このポストバックの設計モデルに慣れて頂きたい。End of Article

.NETエンタープライズWebアプリケーション開発技術大全
Vol.2 ASP.NET 基礎編
定価 3,675円(税込み)

赤間 信幸(マイクロソフト株式会社コンサルティング本部) 著
B5変型判/340p
ISBN 4-89100-428-2
日経BPソフトプレス発行


日経BPソフトプレスの書籍紹介ページへ
マイクロソフトプレスの書籍紹介ページへ

 

 INDEX
  .NETエンタープライズWebアプリケーション 開発技術大全
  ポストバック処理
    1.ポストバック処理の概要
    2.ポストバックの処理シーケンス
    3.ポストバック処理の詳細なランタイム動作
  4.ポストバックの注意すべき点と設計のスタイル

インデックス・ページヘ  「.NETエンタープライズWebアプリケーション開発技術大全」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間