ASP.NETを使用したポストリダイレクトゲット
-
28-10-2019 - |
質問
どうすれば実装できますか redirect-get asp.netのパターン?
ボタンクリックがいくつかの処理を実行します:
<asp:Button id="bbLaunch" OnCommand="bbLaunch_Click" />
ユーザーはボタンをクリックし、宇宙船が起動され、Webページの再表示が表示されます。ユーザーがF5を押すと、警告が表示されます。
問題の解決策はです redirect-get パターン。
その方法は何ですか prg ASP.NETで実装できますか?
質問は次の問題を中心にしています:
- どうすればよいですか
<asp:Button>
aを実行しますPOST
元の形ではない場所に? - 何が来るか ViewState View Stateを読み取らないフォームに投稿するときは?
- 何が来るか ViewState 「リアル」ASPX Webフォームにリダイレクトすると?
- は ViewState 根本的に互換性がありません
ASP.NET再教育後? - asp.netは根本的に互換性がありません Post-Redirect -Get?
- どうやって (つまり、どのコード)「実際の」ASPX Webフォームにリダイレクトしますか?
- どうやって (つまり、どのようなURL)「実際の」ASPX Webフォームにリダイレクトしますか?関係の質問が言及されています
Response.Redirect(Request.RawUrl);
- いつ (つまり、どのイベントハンドラーで)「リアル」ASPX Webフォームにリダイレクトしますか?
- 関連する質問が問題を提起します どうやって フォームデータを投稿します。 HTMLという意味があります フォーム 使用できません - すべてのフォームデータをクエリ文字列に追加する必要があります。これは本当ですか?もしそうなら、なぜですか?そうでない場合は、なぜですか? できる ブラウザはフォームデータをクエリ文字列に入れますか?
- 関連する質問が言及しています
Server.Transfer
. 。使用Server.Transfer
完全に間違っており、再教育後の問題を決して解決しません(なぜなら リダイレクト)。正しい? - どのコード変更が発生する必要がありますか
aspx
またaspx.cs
PRGをサポートするファイル?おそらく、少なくとも、コードをに変更する必要がありますpost
それ以外のどこかMyPage.aspx
.
言い換えると: ASP.NETでどのようにポストリダイレクトゲットをしますか?
ノート: :asp.net(つまり、asp.net mvcではありません)
参照してください
解決
通常、クエリストリングを使用してロード/プロセスのレコードを信号するASPX Webフォームを作成することにより、これを行います。
顧客情報を更新できるページがあるとしましょう。
http://www.mysite.com/customer.aspx
QueryStringのIDを使用してフォームをロードします。
http://www.mysite.com/customer.aspx?CustomerId=42
CodeBehindでは、このようなものがあります。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
int customerId = 0;
if (!string.IsNullOrEmpty(Request.QueryString["CustomerId"]))
{
int.TryParse(Request.QueryString["CustomerId"], out customerId );
}
if (customerId == 0)
{
//handle case when no valid customer id was passed in the qs here
}
else
{
//load customer details, bind controls etc
//make sure to handle the case when no customer was found using the id in the qs
}
}
}
次に、ページのどこかに、変更を保存するボタンがあります。そのボタンには、背後のコードにオンクリックハンドラーがあります。
protected void SaveClicked(object sender, EventArgs e)
{
//save changes to database here
//Redirect if all went well
Response.Redirect("http://www.mysite.com/customer.aspx?CustomerId="
+ idOfSavedCustomer.ToString());
}
それは基本的にそれでなければなりません。リダイレクトにより、ブラウザはRedirect(...)でURLの新しいGETリクエストを発行します。ページがロードされます if (!IsPostBack)
前の投稿で保存したばかりの新しい値でページを実行して初期化します。
このプロセス全体で、ブラウザとサーバー間のトラフィックは次のようになります。
Browser: GET http://www.mysite.com/customer.aspx?CustomerId=42
Server: 200 (send back some html)
Browser: POST http://www.mysite.com/customer.aspx?CustomerId=42 (post data sent in request)
Server: 302 (point to http://www.mysite.com/customer.aspx?CustomerId=42)
Browser: GET http://www.mysite.com/customer.aspx?CustomerId=42
Server: 200 (send html)
中央のステップでは、サーバーは基本的に次のように言っています。
「その投稿のリクエストはあなたが私に送ってくれました、私はそれで終わりました。今ここでこの他のページに到達してください...」
実際、URLが同じページに照会するという事実は重要ではありません。
あなたの弾丸ポイントの質問に応答したいくつかの黙想:
- 元のフォームではない場所への投稿をどのように実行できますか?
これを設定することでこれを行うことができます action
フォームの属性、またはあなたは PostBackUrl
ボタン上。
- View Stateを読み取らないフォームに投稿すると、ViewStateはどうなりますか?
依存します。フォームを別のページに単に投稿するだけで、<%@ fortionPageType .../>ディレクティブを使用して、投稿がどこから来たのか「新しい」ページを伝えることができます。これにより、新しいページに投稿されたデータを使用して単純に動作します。見る 詳細については、このリンク.
- 「リアル」ASPX Webフォームにリダイレクトすると、ViewStateはどうなりますか?
View StateはPOSTリクエストで送信されます。リダイレクトすると、ブラウザは新しいページをロードし、独自のViestateを作成します。
- ViewStateは、ASP.NET後のRedirect-Getと根本的に互換性がありませんか?
あなたがそれをどのように見るかに依存します。リダイレクト後、新しいページは以前にページのビューステートにアクセスできません。
- ASP.NETは根本的にredirect-getと根本的に互換性がありませんか?
いいえ。上記の例を参照してください。
- どのように(つまり、どのコード)「実際の」ASPX Webフォームにリダイレクトしますか?
Response.Redirect(URL)。これにより、ブラウザに応答が送信され、新しいGetリクエストを実行するように伝えます。
- いつ(つまり、どのイベントハンドラーで)「実際の」ASPX Webフォームにリダイレクトしますか?
POSTリクエストを処理するために必要なすべての作業を実行したとき。
- 関連する質問は、フォームデータの投稿方法の問題を提起します。 HTMLフォームを使用できないという意味があり、すべてのフォームデータをクエリ文字列に追加する必要があります。これは本当ですか?もしそうなら、なぜですか?そうでない場合は、なぜですか?ブラウザはフォームデータをクエリ文字列に配置できますか?
POSTリクエストのリダイレクトは十分にサポートされておらず、おそらく避ける必要があります。 HTTP応答307を使用して(一部のブラウザで)実行できます。それを行うと、サーバーはブラウザに効果的に指示します。リクエストを処理しません。代わりにこの他のページに投稿してください".
- 関連する質問は、server.transferに言及しています。 Server.Transferを使用することは完全に間違っています。また、リダイレクト後の問題を解決することはありません(リダイレクトがないため)。正しい?
Server.Transfer(...)は、サーバー側で行われているものです。ブラウザはそれを認識していません。基本的に、ページはserver.transferを使用して、他のページに何らかの処理を行わせるようにします。そのページは、ブラウザに応答を送信する責任があります。しかし、ブラウザは、それが応答した元のページであると考えるでしょう。
- PRGをサポートするために、ASPXまたはASPX.CSファイルでどのようなコード変更が発生する必要がありますか?おそらく、少なくとも、mypage.aspx以外の場所に投稿するためにコードを変更する必要があります。
いいえ、定期的なポストバックを使用できます。トリックは、投稿されたデータを処理した後にrepsonse.redirectを実行するページに1つ(または数)の特定のイベントハンドラーをページに配置することです。
他のヒント
Q)元のフォームではない場所への投稿をどのように実行できますか?
a)PRGでは、別のページに投稿しないで、同じページに投稿します(リンクしたウィキペディアページの図を参照)。ただし、そのページからの応答は30倍の応答でなければなりません(通常は302です。 。)
Q)View Stateを読み取らないフォームに投稿すると、ViewStateはどうなりますか?
a)投稿するとビュー状態がありますが、そこには、あなたがしている新しいページのためにビュー状態がありません。
Q)「リアル」ASPX Webフォームにリダイレクトすると、ViewStateはどうなりますか?
a)上記の場合、ページにリダイレクトするビュー状態はもうありません。
Q)ViewStateは根本的にASP.NETと互換性がありませんか?
a)ViewStateはASP.NETと互換性がありません。リダイレクトされているページをレンダリングするには、(ほとんど)P/R/Gの場合は役に立たない。
Q)ASP.NETは根本的にredirect-getと互換性がありませんか?
a)いいえ - ただし、上記のように、1つのページを使用してViewStateにすべての状態を維持することに過度に依存することはできません。とはいえ、ASP.MVCはP/R/Gにははるかに優れています
Q)(つまり、どのコード)「実際の」ASPX Webフォームにリダイレクトしますか?
a)respons.redirect( "new_page_you_are_redirecting_to.aspx")in the bblaunch_click old_page_you_are_posting_from.aspxのメソッド
Q)(つまり、どのようなURL)「実際の」ASPX Webフォームにリダイレクトしますか?関係の質問は、respons.redirect(request.rawurl)に言及しています。
a)上記を参照してください
Q)(つまり、どのイベントハンドラーで)「実際の」ASPX Webフォームにリダイレクトしますか?
a)ボタンを処理した後、データをDB(またはセッションなど)に保存し、それ以前は応答ストリームに他のものを書き込む前に。
Q)関連する質問は、フォームデータの投稿方法の問題を提起します。 HTMLフォームを使用できないという意味があり、すべてのフォームデータをクエリ文字列に追加する必要があります。これは本当ですか?
a)いいえ - ASP.NET WebFormsのボタンを押すと、ページに戻ります。
Q)もしそうなら、なぜですか?そうでない場合は、なぜですか?
a)これはこれよりも簡単です。イメージング2ページ:first_page.aspおよびsecond_page.aspx。 first_page.aspxにはボタンがあります(ユーザーが記入したテキストボックスなど、他のASP.NET Webコントロールとともに)ボタンを押すと、first_page.aspxに投稿が作成されます。データを処理した後(これは抽象化されていますが、viewstate内にある可能性が高い)、respons.redirectを使用してユーザーをsecond_page.aspxにリダイレクトします。 second_page.aspxは、必要なものを表示できます。コントロールや入力を含むfirst_page.aspxに類似したUIを表示する(または必要な)場合は、セッション、Cookie、urlをQueryString Paramsとして保存したいと思います。 second_page.aspxのこれらのコントロール。 (ただし、second_page.aspxにfirst_page.aspxに似たものを表示する必要がない場合があります。したがって、ここには一般的なルールはありません。)
Q)ブラウザはフォームデータをクエリ文字列に配置できますか?
a)はい、投稿の代わりに取得する方法を設定した場合。これを行うためにウェブフォームをオーバーライドすることはできません。これはPRGには必要ありません
Q)関連する質問は、サーバーに言及しています。Transfer。 Server.Transferを使用することは完全に間違っています。また、リダイレクト後の問題を解決することはありません(リダイレクトがないため)。正しい?
a)本質的に
Q)PRGをサポートするために、ASPXまたはASPX.CSファイルでどのコード変更が発生する必要がありますか?おそらく、少なくとも、mypage.aspx以外の場所に投稿するためにコードを変更する必要があります。
a)コードは引き続き戻って(上記のように)投稿する必要がありますが、mypage.aspxはボタンハンドラーの新しいページに再ダイレクトする必要があります。
リダイレクト後のパターンは、Web形式で使用できます。 MVC NerddinnerアプリケーションをWebフォームに変換することで、これがどのように行われるかを示しました。 http://navigationnerddinner.codeplex.com/ 。ナビゲーションの詳細をまったく同じように保持しているので、PRGパターンの例はたくさんあります。
ただし、F5/更新の問題を回避する別の方法があります。ページをupdatePanel(ASP.NET AJAXの一部)でラップすると、すべてのポストバックが部分ページリクエストに変換されます。これは、F5が押されたときに、元のGETリクエストのみを更新することを意味します(後続の投稿がなかったため)、警告が表示されないことを意味します。 (注、JavaScriptが無効になっている場合、警告は引き続き表示されます)。
Post Redirect Getの正確なステップはこれです。
データを完成させるフォームがあり、有効な送信(投稿)の後、データベースに挿入し、確認IDを指定し、この確認IDを使用してこの確認IDを使用してユーザーをページにリダイレクトします。リダイレクトの後(取得)として、すべてのF5-Refreshがデータを読み取り、再度挿入しないように。
挿入用のコードは、確認を表示するコードとは異なります。別のページを作成することもできます。読み取り専用のテキストボックスで同じページを作成できます。
リダイレクトは単純です Responce.Redirect
asp.netの関数
投稿とリダイレクトの作成の後、以前のアクションに接続することだけが確認コード(ViewStateではありません)だけだと考えています。
この方法のマイナスは、実際にはリフレッシュを認識していないことであり、再び同じデータを再度挿入しないでください。
代替案は、リフレッシュを認識し、リダイレクトを行わないことです。ポストバックの更新を認識することにより、ユーザーに単一のメッセージで同じデータを挿入することを避けることができます。そのためのインターネットにはいくつかの例があり、私は成功したものを実装しています。
一例: http://www.codeproject.com/tips/319955/how-to-prevent-re-post-cation-caused-by-pressing-b
あなたは呼び出すことができます Response.redirect 別の場所に行く方法。
これに入るものがいくつかあります。
をセットする アクション メインページのフォームの属性(それを呼びましょう launchform.aspx)「プロキシ」ページのURLに等しい(proxylaunchform.aspx).
u003Cform id="form1" runat="server" action="ProxyLaunchForm.aspx" method="POST">
(オプション)名前の隠された入力を追加します Redirecturl 形式に、と伝えるURLを評価します proxylaunchform.aspx ローンチの実行が終了したら、どこにリダイレクトするか(PRGのR部分)。
今 proxylaunchform.aspx, 、実装は内部で行われる必要があります page_load イベントハンドラー。これは、フォームポストデータにアクセスできるためです。ここで起動を実行します。
その後(inも page_load)、リダイレクトを実行します(を使用して Redirecturl #2から、または単に参照ページURLを使用してください):
Response.redirect(request.Params ["redirecturl"] ?? request.urlreferrer.absoluteuri);
ビュー状態の問題はまだあります。これに対処する最も簡単な方法は、ビュー状態がどのように持続するかを変えることだと思います。通常、それはページ上の隠された入力要素に保存され、ポストバックで取得されます(もちろん、HTTPの無国籍性のためにリダイレクトの後に失われることを意味します)。ただし、ASP.NETが使用する方法をオーバーライドし、使用することができます。 セッション 代わりに(そのようにして、PRGプロキシアクションの後でも存在します)。だから、ついに...
の launchform.aspx.cs, 、ベースクラスAサブクラスとして使用します ページ それはオーバーライドします SavePageStateToperSistencemedium と LoadPageStateFromperSistenCemedium 隠されたフォームフィールドからではなく、セッションからそれらを保存/取得する方法。以下を参照してください(および これがどのように機能するかについての詳細を次に示します。).
*
public class PersistViewStateToSession : Page
{
protected override void SavePageStateToPersistenceMedium(object viewState)
{
// serialize the view state into a base-64 encoded string
LosFormatter los = new LosFormatter();
StringWriter writer = new StringWriter();
los.Serialize(writer, viewState);
// save the string to session
Session["LaunchViewState"] = writer.ToString();
}
protected override object LoadPageStateFromPersistenceMedium()
{
if (!Session["LaunchViewState"] == null)
return null;
else
{
string sessionString = (string)Session["LaunchViewState"];
// deserialize the string
LosFormatter los = new LosFormatter();
return los.Deserialize(viewStateString);
}
}
}