トップ回答者
POSTデータ受信後にページを表示したい

質問
-
こんにちは、お世話になっています。
ASP.NET4.0(VB)でWEBサイトを開発しています。
その中に、POSTデータを受信する機能がありまして、
POSTデータは無事に受信することができました。
ただ、受信後に完了画面のようなページを表示させたいのですが、
POSTデータ受信後にブラウザにページが表示されません。
そこで、Server.TransferやResponse.Redirectを使用してみましたが、
指定したページにデバッグ実行でPage_Load内には入ってきますが、
その後、やはりブラウザには何も表示されません。
POST受信するaspxが「a.aspx」とした場合、ブラウザには「a.aspx」は
表示されないものなのでしょうか?
また、POST受信後「a.aspx」から「b.aspx」へServer.TransferやResponse.Redirectで
遷移させても、「b.aspx」はブラウザには表示されないものなのでしょうか?
簡単なところかもしれませんが、調べても解答にたどりつけずご質問させていただきました。よろしくお願いします。
回答
-
> インスタンスがそもそもブラウザと違うから表示されないのですね。
インスタンスが違うというよりも、a.aspx を要求しているのは Web サ
ーバーであって、応答は Web サーバーに返ってくるからです。応答が返ってきても、「送信側webページ」にはそれを受けるコードが
ありません(少なくともアップされたコードには)。受けるコードを
追加したとしても、受けた応答をブラウザに渡さない限り、ブラウザで
応答を見るすべはないです。「送信側webページ」に、a.aspx の応答受けて iframe などにそれを表
示する仕組みを作り、されにセキュリティの問題を解決できれば、やり
たいことを実現できるかもしれません。以下のような感じです。
送信側ページ
<%@ Page Language="C#" %> <%@ Import Namespace="System.Net" %> <%@ Import Namespace="System.IO" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { Encoding enc = Encoding.GetEncoding("UTF-8"); string url = "http://msdntestnew/128-PageToPost.aspx"; string param = "testrequest=" + HttpUtility.UrlEncode("POSTデータ", enc); byte[] data = enc.GetBytes(param); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; Stream reqStream = req.GetRequestStream(); reqStream.Write(data, 0, data.Length); reqStream.Close(); HttpWebResponse res = (HttpWebResponse)req.GetResponse(); Stream resStream = res.GetResponseStream(); StreamReader sr = new StreamReader(resStream, enc); string response = sr.ReadToEnd(); Session["PostedPageResponse"] = enc.GetBytes(response); sr.Close(); } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>HttpWebRequest で POST</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" Text="POST" OnClick="Button1_Click" /> </div> <iframe id="iframe1" runat="server" src="128-HttpHandler.ashx" /> </form> </body> </html>
受信側ページ
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { Encoding enc = Encoding.GetEncoding("UTF-8"); string sPostData = ""; int len = Request.ContentLength; if (len > 0) { byte[] bdata = Request.BinaryRead(len); sPostData = enc.GetString(bdata); sPostData = HttpUtility.UrlDecode(sPostData, enc); } Label1.Text = "POST されたデータを受信しました"; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>POST されたデータの受信サイト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server"></asp:Label> </div> </form> </body> </html>
HttpHandler
<%@ WebHandler Language="C#" Class="_128_HttpHandler" %> using System; using System.Web; using System.Web.SessionState; // HttpHandler で Session に read/write するためには // IRequiresSessionState インターフェイスを継承する。 public class _128_HttpHandler : IHttpHandler, IRequiresSessionState { public void ProcessRequest (HttpContext context) { byte[] data = (byte[])context.Session["PostedPageResponse"]; if (data != null) { context.Response.BinaryWrite(data); context.Session.Remove("PostedPageResponse"); } context.Response.End(); } public bool IsReusable { get { return false; } } }
- 編集済み SurferOnWww 2012年1月16日 14:29 見栄え修正
- 回答としてマーク ボビン 2012年1月18日 1:19
すべての返信
-
> その中に、POSTデータを受信する機能がありまして、POSTデータは無事に受信することができました。
こういう書き方しているということは、POSTの送信元は普通のWEBページじゃないってことでしょうか。
普通に想定されるのはWEBページ上から送信ボタンを押してサーバにデータを送り処理して結果表示
だと思いますが、もし違うのならそれもご説明されたほうが良いと思います。
> POST受信するaspxが「a.aspx」とした場合、ブラウザには「a.aspx」は表示されないものなのでしょうか?
そんなことはないと思います。受け取った後の処理でおかしくなっている可能性もあると思います。
a.aspxの内容を最小限にして試してみると良いと思います。 -
mars12さん、こんにちは。
> こういう書き方しているということは、POSTの送信元は普通のWEBページじゃないってことでしょうか。
> 普通に想定されるのはWEBページ上から送信ボタンを押してサーバにデータを送り処理して結果表示
> だと思いますが、もし違うのならそれもご説明されたほうが良いと思います。
送信元は特に変わったことはありません。
想定されている通りです。本番環境では外部からPOSTで送信されてきますが、
開発環境ではASP.NETで送信webアプリを作成してテストしています。
> そんなことはないと思います。受け取った後の処理でおかしくなっている可能性もあると思います。
> a.aspxの内容を最小限にして試してみると良いと思います。
やはりデフォルトではブラウザに表示されますか。何が原因で表示されないのでしょうか。
すでに最小限のコードで試しているつもりですが、伝わりやすいようにコードを記載します。
a.aspx.vb
コード↓↓↓↓↓*******************************************************************
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim enc As Encoding = Encoding.GetEncoding("Shift_JIS") ' Shift_JISを指定
Dim sPostData As String = ""
' 受信したPOSTデータをURLデコード
Dim len As Integer = Request.ContentLength
If len <> 0 Then
Dim bdata As Byte() = Request.BinaryRead(len)
sPostData = enc.GetString(bdata)
sPostData = HttpUtility.UrlDecode(sPostData, enc)
End If
Dim aryPostData As String()
aryPostData = Split(sPostData, "=", -1, CompareMethod.Binary)
Dim iSt As Integer = 1
Dim iGet As Integer = 0
' 1:会社コード
' 2:お客様番号
' 3:商品/サービス識別番号
' POSTデータを項目毎に分割(固定長)
iGet = 5
Session("KaisyaCd") = NewMidB(aryPostData(1), iSt, iGet)
iSt += iGet
iGet = 20
Session("MBR_ID") = NewMidB(aryPostData(1), iSt, iGet)
iSt += iGet
iGet = 3
Session("SyouhinNo") = NewMidB(aryPostData(1), iSt, iGet)
iSt += iGet
' 画面遷移を指定してみる
'Server.Transfer("b.aspx")Response.Redirect("b.aspx")
End Sub
コード↑↑↑↑↑*******************************************************************
コード下部のServer.TransferやResponse.Redirectを削除しても、「a.aspx」がブラウザに表示されません。
よろしくお願いします。 -
デバッグ実行は正常に終わっているのでしょうか? Server.Transferが実行されれば、さすがにb.aspxに遷移する気がするのですが・・・
ブラウザになにかスクリプトエラーのようなメッセージが左下などに表示されていませんか?
あまり関係ないかもしれませんが、ブラウザのキャッシュをクリアしてみたり、ASP.NETが作成しているテンポラリのフォルダを消してみてはいかがでしょうか?(参考)
Temporary ASP.NET Files フォルダの内容
http://msdn.microsoft.com/ja-jp/magazine/cc163496.aspx
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/ -
trapemiyaさん、こんにちは。
> そこで、Server.TransferやResponse.Redirectを使用してみましたが、
> 指定したページにデバッグ実行でPage_Load内には入ってきますが、
> その後、やはりブラウザには何も表示されません。
b.aspxには遷移しています。デバッグ実行でPage_Loadの最後までいきますが、ブラウザに表示されません。
> ブラウザになにかスクリプトエラーのようなメッセージが左下などに表示されていませんか?
そのブラウザですが、新たにウィンドウが立ち上がるとか新たにタブが増えるとか動きが何もないのです。
送信元webアプリだけがブラウザに表示されている状態です。
> あまり関係ないかもしれませんが、ブラウザのキャッシュをクリアしてみたり、ASP.NETが作成しているテンポラリのフォルダを消してみてはいかがでしょうか?
試してみます。情報ありがとうございます。
-
送信元はどうやってPOSTでしょうか?
HttpWebRequestを利用しますか あるいは、ButtonのPostBackUrlを設定しますか
送信元webページのformタグに
<form runat="server" action="http://www.xxx.com.jp/a.aspx">
...
</form>
actionをつければ、いかがでしょうか
- The blog of typewriter職人
- Convert C# to VB.NET
- /*If my concept is wrong ,please correct me.Thanks.*/
-
> こういう書き方しているということは、POSTの送信元は普通のWEBページじゃないってことでしょうか。
> 普通に想定されるのはWEBページ上から送信ボタンを押してサーバにデータを送り処理して結果表示
> だと思いますが、もし違うのならそれもご説明されたほうが良いと思います。
送信元は特に変わったことはありません。
想定されている通りです。本番環境では外部からPOSTで送信されてきますが、
開発環境ではASP.NETで送信webアプリを作成してテストしています。
ブラウザーに表示した Web ページから POST するのかと思いきや、
> HttpWebRequestを利用しますか あるいは、ButtonのPostBackUrlを設定しますか
送信元はHttpWebRequestを利用しています。
HttpWebRequest を利用しているとのこと。
結局のところ、どのようにして POST しているのでしょうか?
ここの部分が非常に重要なポイントだと思うのですが。 -
totojo さんのレスとダブルところがありますが・・・
> 送信元はHttpWebRequestを利用しています。
と言いながら、>> actionをつければ、いかがでしょうか
>
> つけてみたところ、a.aspxに遷移しましたが、POSTデータの中身が変わりました。といっているのが矛盾していて訳がわかりませんが、結局 POST する先が
間違っていて、a.aspx を要求していなかったということでしょうか?でも、そうだとすると、action を指定する前に、
> 指定したページにデバッグ実行でPage_Load内には入ってきますが、
というのがまた矛盾しているし・・・
状況を整理して、ボビンさんの個人的環境をなにも知らない回答者が理解で
きるように書いていただけませんか。できれば、回答者のほうで問題を再現できる必要最小限のコードをアップし
てください。その際は a.aspx だけでなく、POST するページもお願いします。また、a.aspx
の方もコピペすればそのまま動くようにしてください(定義不明なメソッド
などを含めないで)。 -
皆様、混乱させてしまったようで申し訳ありません。
整理して、記載します。
以下がシンプルにしたコードです。伝わりますでしょうか?
■送信側
Protected Sub Btn_Post_Click(sender As Object, e As System.Web.UI.ImageClickEventArgs) _
Handles Btn_Post.Click
Dim enc As Encoding = Encoding.GetEncoding("Shift_JIS")
Dim url As String = "http://localhost:51103/a.aspx"
Dim param As String = ""
param = "testrequest=" & HttpUtility.UrlEncode("POSTデータ", enc)
Dim data As Byte() = enc.GetBytes(param)
' リクエストの作成
Dim req As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
req.ContentLength = data.Length
' ポスト・データの書き込み
Dim reqStream As Stream = req.GetRequestStream()
reqStream.Write(data, 0, data.Length)
reqStream.Close()
' 「aへ遷移しました」ページへリダイレクトする
Server.Transfer("Moved.aspx")
End Sub
■受信側(a.aspx)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim enc As Encoding = Encoding.GetEncoding("Shift_JIS")
Dim sPostData As String = ""
' 受信したPOSTデータをURLデコード
Dim len As Integer = Request.ContentLength
If len <> 0 Then
Dim bdata As Byte() = Request.BinaryRead(len)
sPostData = enc.GetString(bdata)
sPostData = HttpUtility.UrlDecode(sPostData, enc)
End If
Session("post_data") = sPostData
' sPostDataには正しく「POSTデータ」が格納されている事は確認
' このあとa.aspxがブラウザに表示されないので、
' b.aspxに遷移させてみる
Server.Transfer("b.aspx")
'Response.Redirect("b.aspx")
End Sub
■b.aspx
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' ここにブレークポイントを設定し、遷移は確認できるが、
' b.aspxはブラウザに表示されない
Me.Lbl_PostData.Text = CStr(Session("post_data"))
End Sub
■テスト方法
送信側webページをブラウザに表示させて、Btn_Postをクリックすると、Btn_Post_Clickに入り、
別PJで実行させておいた、受信用の"http://localhost:51103/a.aspx"へ遷移します。
(この時点でブラウザには送信側の"Moved.aspx"が表示されます)
あとは、a.aspxのPage_Load内でPOSTデータを展開後、Server.Transfer("b.aspx")で
b.aspxのPage_Loadにデバッグ実行で遷移しますが、
ブラウザにはb.aspxは表示されません。
ここでb.aspxを表示させたいと思っています。
伝わりましたでしょうか?
よろしくお願いします。
-
なるほど、わかりました。インスタンスがそもそもブラウザと違うから表示されないのですね。
b.aspxのコードにデバッグ実行できているので、Page_Loadの後は、b.aspxがブラウザに表示されるものと思っていました。
今回実現したかった事は、決済代行業者からの返りをユーザーへブラウザ上で表示してお知らせしたかったのですが、
こちら側で表示させようとせず、お知らせページだけ用意しておいて、
決済代行業者がこちらへPOST送信後に、こちらの用意したお知らせページURLへリダイレクトしてもらう、という流れですね。
ようやくすっきりと理解できました。ありがとうございました。
- 編集済み ボビン 2012年1月16日 3:32
-
> インスタンスがそもそもブラウザと違うから表示されないのですね。
インスタンスが違うというよりも、a.aspx を要求しているのは Web サ
ーバーであって、応答は Web サーバーに返ってくるからです。応答が返ってきても、「送信側webページ」にはそれを受けるコードが
ありません(少なくともアップされたコードには)。受けるコードを
追加したとしても、受けた応答をブラウザに渡さない限り、ブラウザで
応答を見るすべはないです。「送信側webページ」に、a.aspx の応答受けて iframe などにそれを表
示する仕組みを作り、されにセキュリティの問題を解決できれば、やり
たいことを実現できるかもしれません。以下のような感じです。
送信側ページ
<%@ Page Language="C#" %> <%@ Import Namespace="System.Net" %> <%@ Import Namespace="System.IO" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { Encoding enc = Encoding.GetEncoding("UTF-8"); string url = "http://msdntestnew/128-PageToPost.aspx"; string param = "testrequest=" + HttpUtility.UrlEncode("POSTデータ", enc); byte[] data = enc.GetBytes(param); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; Stream reqStream = req.GetRequestStream(); reqStream.Write(data, 0, data.Length); reqStream.Close(); HttpWebResponse res = (HttpWebResponse)req.GetResponse(); Stream resStream = res.GetResponseStream(); StreamReader sr = new StreamReader(resStream, enc); string response = sr.ReadToEnd(); Session["PostedPageResponse"] = enc.GetBytes(response); sr.Close(); } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>HttpWebRequest で POST</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" Text="POST" OnClick="Button1_Click" /> </div> <iframe id="iframe1" runat="server" src="128-HttpHandler.ashx" /> </form> </body> </html>
受信側ページ
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { Encoding enc = Encoding.GetEncoding("UTF-8"); string sPostData = ""; int len = Request.ContentLength; if (len > 0) { byte[] bdata = Request.BinaryRead(len); sPostData = enc.GetString(bdata); sPostData = HttpUtility.UrlDecode(sPostData, enc); } Label1.Text = "POST されたデータを受信しました"; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>POST されたデータの受信サイト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server"></asp:Label> </div> </form> </body> </html>
HttpHandler
<%@ WebHandler Language="C#" Class="_128_HttpHandler" %> using System; using System.Web; using System.Web.SessionState; // HttpHandler で Session に read/write するためには // IRequiresSessionState インターフェイスを継承する。 public class _128_HttpHandler : IHttpHandler, IRequiresSessionState { public void ProcessRequest (HttpContext context) { byte[] data = (byte[])context.Session["PostedPageResponse"]; if (data != null) { context.Response.BinaryWrite(data); context.Session.Remove("PostedPageResponse"); } context.Response.End(); } public bool IsReusable { get { return false; } } }
- 編集済み SurferOnWww 2012年1月16日 14:29 見栄え修正
- 回答としてマーク ボビン 2012年1月18日 1:19
-
SurferOnWwwさん、サンプルまでありがとうございます。> インスタンスが違うというよりも、a.aspx を要求しているのは Web サーバーであって、応答は Web サーバーに返ってくるからです。> 応答が返ってきても、「送信側webページ」にはそれを受けるコードがありません(少なくともアップされたコードには)。受けるコードを> 追加したとしても、受けた応答をブラウザに渡さない限り、ブラウザで応答を見るすべはないです。わかりました。整理してみると、URLをブラウザに入力した時と、POSTでの受信時のブレークポイントでの動きが同じだったため、処理がPage_Loadの最後までいった後は、ブラウザに表示できると思い込んでしまった事、外部サイトがこちらへPOST送信を行い、それで外部サイト側は終了、後はこちらでPOST受信後の完了ページ等を表示させる、と思い込んだ事が間違いでした。おっしゃるような原則を頭にしっかりと入れて開発します。サンプルは送信側ページで1プロジェクト、受信側ページとHttpHandlerで1プロジェクトでしょうか?ただそれだとSession("PostedPageResponse")にはアクセスできなくなると思うので、送信側ページ、受信側ページとHttpHandlerで1プロジェクトでしょうか?
- 編集済み ボビン 2012年1月17日 4:23