.NET TIPS

[ASP.NET]異なるWebフォームにポスト・データを送信するには?[2.0のみ、C#、VB]

山田 祥寛
2006/02/03

 ポストバックは、ASP.NETを理解するうえで欠かすことのできない、重要な概念の1つだ。ASP.NETでは、Webフォーム上で発生したイベント情報を自分自身に対してポスト(POST)することで(これを「ポストバック」と呼ぶ)、<Windowsアプリケーション的な>イベント処理モデルを疑似的に実現している。ポストバックは、ASP.NETのイベント処理モデルを支える柱であるといってもよいだろう。

 もっとも、ASP.NET 1.xにおけるポストバックには課題もあった。というのも、ASP.NET 1.xでは自分自身に対してしかポストすることができない。例えばページAからページBへとポストしたい場合にも、いったんページAのイベント・プロシージャでポストバックを受けておいて、Server.TransferメソッドでページBに転送するという2段階の手続きが必要であった。具体的には、以下のようなコードを記述しなければならなかった。

Sub Button1_Click(sender As Object, e As System.EventArgs)
  Server.Transfer("crossPage2.aspx")
End Sub
void Button1_Click(object sender, System.EventArgs e) {
  Server.Transfer("crossPage2.aspx");
}
ASP.NET 1.xでページ間の移動を行うためのコード例(上:C#、下:VB.NET)
従来のASP.NETでは、この例のように、いったんイベント・プロシージャでポストバックを受けておいて、Server.Transferメソッドで転送するという2段階の手続きが必要だ。

 しかし当然のことながら、ただページ遷移を行うためだけにイベント・プロシージャを記述しなければならないのは、あまりうれしいことではない。そこで、ASP.NET 2.0からは「ページ間ポスティング(クロスページ・ポストバック)」という機能が導入された。さっそく、具体的なコードを見てみよう。

<%@ Page Language="VB" %>
<html>
<head>
<title>ページ間ポストバック</title>
</head>
<body>
<form runat="server">
  <asp:TextBox id="TextBox1" runat="server" />
  <asp:Button id="Button1" runat="server"
    PostBackUrl="crossPage_after_vb.aspx" Text="送信" />
</form>
</body>
</html>
データ送信元のWebフォーム(crossPage_before.aspx)
ボタンをクリックすることでcrossPage_after_vb.aspxへポストバックする。

 ページ間ポスティングを利用するには、ポストバックの発生元となるコントロール(この例ではButtonコントロール)のPostBackUrl属性にポスト先のURL(ここではcrossPage_after_vb.aspx)を指定するだけだ。これで、Buttonコントロールがクリックされたタイミングで、ページの内容がcrossPage_after_vb.aspxにポストされる。

 ただし、ページ間ポスティングでは、ポスト先でのサーバ・コントロールへのアクセスの方法がこれまでとは変わってくるので注意が必要だ。

 具体的なコードを以下で見てみよう。なお、C#版のコードを実行するには、crossPage_before.aspx上のPostBackUrl属性も合わせて変更すること(本稿の例ではcrossPage_after_cs.aspxに変更した)。

<%@ Page Language="C#" %>
<script runat="server">
void Page_Load(Object sender, EventArgs e){
  // ページ間ポスティングでページが呼び出されたかをチェック
  if (Page.PreviousPage != null) {
    if (Page.PreviousPage.IsCrossPagePostBack) {
      // ポスト元ページのテキストボックスの値をラベルに反映
      TextBox PrevText =
        (TextBox)Page.PreviousPage.FindControl("TextBox1");
      Label1.Text = PrevText.Text;
    }
  }
}
</script>
<html>
<head>
<title>ページ間ポストバック</title>
</head>
<body>
<form runat="server">
  こんにちは、<asp:Label id="Label1" runat="server" />さん!
</form>
</body>
</html>
ページ間ポスティングによる値の取得(C#版:crossPage_after_cs.aspx)

<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(sender As Object, e As EventArgs)
  ' ページ間ポスティングでページが呼び出されたかをチェック
  If Not Page.PreviousPage Is Nothing Then
    If Page.PreviousPage.IsCrossPagePostBack Then
      ' ポスト元ページのテキストボックスの値をラベルに反映
      Dim PrevText As TextBox= _
        CType(Page.PreviousPage.FindControl("TextBox1"), TextBox)
      Label1.Text = PrevText.Text
    End If
  End If
End Sub
</script>
<html>
<head>
<title>ページ間ポストバック</title>
</head>
<body>
<form runat="server">
  こんにちは、<asp:Label id="Label1" runat="server" />さん!
</form>
</body>
</html>
ページ間ポスティングによる値の取得(VB版:crossPage_after_vb.aspx)

 ここで注目していただきたいポイントは、以下の2点だ。

(1)ポスト元のページを取得するのはPage.PreviousPageプロパティ

 ポスト元のページ(Pageオブジェクト)は、Page.PreviousPageプロパティで取得が可能だ。あとは、FindControlメソッドで値を取得したいコントロールへの参照を取得すればよい。ちなみに、FindControlメソッドは戻り値をObject型として返すので、コントロールのメンバにアクセスする必要がある場合には、CType関数(C#ではキャスト構文)でデータ型の変換を行う必要がある。

(2)正しいページ遷移が行われたかを確認する

 ページ間ポスティングを利用する場合、呼び出しが正しいページから行われたかどうかを確認することは重要だ。本稿の例ならば、crossPage_before.aspxから呼び出されることを想定して記述されたcrossPage_after_vb.aspx/crossPage_after_cs.aspxが(例えば)クライアントから直接に呼び出されることは、開発者が意図しない挙動をする可能性があるという意味で好ましくない。

 そこで、ページ間ポスティングを利用する場合には、以下のステップを踏んで、リクエストがページ間ポスティングによるものであることを確認する必要がある。

  • Page.PreviousPageプロパティがNothing(C#ではnull)でないこと
  • Page.PreviousPage.IsCrossPagePostBackプロパティがTrueを返すこと

 Page.PreviousPageプロパティがNothing(null)である場合、該当のページは直接呼び出されたか、自分自身のポストバックによって呼び出されたことを意味する。ページ間ポスティングを利用したならば、Page.PreviousPageプロパティにはページ参照が含まれているはずだ。

 多くの場合、これだけでも十分なチェックに見えるかもしれないが、実はNothing(null)チェックだけでは完全とはいえない。というのも、Server.Transferメソッドによる転送が行われた場合にも、Page.PreviousPageプロパティには転送元ページへの参照がセットされるからだ。

 ページ間ポスティングだけを処理の対象にするためには、ここでIsCrossPagePostBackプロパティをチェックする必要がある。IsCrossPagePostBackプロパティはページ間ポスティングを送信したかどうかをブール値で返すものだ。Server.Transferメソッドによって転送された場合、IsCrossPagePostBackプロパティはFalseを返す。

 なお、ここで注意していただきたいのは、チェックするのは現在のページのIsCrossPagePostBackプロパティ(Page.IsCrossPagePostBackプロパティ)ではなく、ポストバック元のIsCrossPagePostBackプロパティ(Page.PreviousPage.IsCrossPagePostBackプロパティ)であるという点だ。現在のページのIsCrossPagePostBackプロパティは、常にfalseを返すので、注意してほしい。

 以上を理解したら、さっそくcrossPage_before.aspxを実行してみよう。



ページ間ポスティングの実行結果
crossPage_before.aspxで入力した値が、crossPage_after_vb.aspx/crossPage_after_cs.aspxに反映される。

 この画面の例のように、crossPage_before.aspxで入力した値が、crossPage_after_vb.aspx/crossPage_after_cs.aspxで正しく反映されていれば成功だ。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:Webフォーム 処理対象:ポストバック

この記事と関連性の高い別の.NET TIPS
[ASP.NET]ページ間ポストバックでポスト元ページの情報に簡単にアクセスするには?
[ASP.NET]ポストとポストバックの違いは?
[ASP.NET]DataGridコントロールでビューステートを使用せずにページ表示するには?
[ASP.NET]DataGridコントロールでページ表示するには?
ASP.NETでボタンのクリック時に確認メッセージを表示するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


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 記事ランキング

本日 月間