2009-08-16 10 views
1

投稿経由でフォームを送信し、同じURLまたは別のURLにリダイレクトするASP.NET MVCパターンは、コード作成が非常に簡単です。ASP.NET MVCのPOSTリダイレクトGETにはどのような方法がありますか?

は、このシナリオを想像:

  1. ユーザーは、彼らはそれを編集して、そのページ上で狂った何かを見る42.
  2. を表示および編集製品に/製品/ 42 /編集となり、保存ヒット。アクションは、データを更新し、またはにリダイレクトします。これは、/製品/ 42 /編集
  3. にPOSTを引き起こし/製品/ 42 /編集
  4. のビューを返します。ユーザーは、更新されたデータを見ていますハッピー。
  5. 1時間後に、他の誰かが製品#42を混乱させるかどうかを確認するために、リフレッシュをクリックします。
  6. 最後に/products/42/editの検索がPOSTだったので、ブラウザはフォームデータの再送信を求めます。これは他人のデータを上書きする可能性があるので、迷惑なが危険です。

私はPOSTをするために、2つの異なるURLを使用して(たとえば/製品/ 42 /編集/製品/ 42)、ブラウザは、まだ再投稿をお願いすることとなってもいることを恐れますデータを破壊する可能性があります。私は間違っていますか?

製品の変更をサブミットした後、ユーザーはリフレッシュして更新されたビューを得ることができます。

更新私の質問と私のデザインは混乱していました。 POSTとGETの間でURL(アクション)を共有するのは悪い考えでした。その2つが異なる場合、私は "リフレッシュの原因rePOST"の問題がないと仮定するのは当然ですか?

+2

私はこの問題を理解していません。ユーザーが編集内容を送信すると、ユーザーがデータベースに書き込まれ、ユーザーは製品の現在のビューに移動します。彼らはF5と製品アップデートの現在のビューにヒットしました。問題はどこだ? –

+0

コントローラのメソッドとビューにコードの一部を投稿することを検討してください。その結果、何が起こっているのかがわかります。 –

+0

私は質問を明確にしました(私は願っています)。 POSTとGETの間でURLを共有するのは悪い考えでした。その2つが異なる場合、私は "リフレッシュの原因rePOST"の問題がないと仮定するのは当然ですか? –

答えて

5

更新:はい。

/product/{id} /を表示用に、/ product/{id} /編集を編集用に、編集後に/ product/{id} /にリダイレクトします。

問題を解決しました。/product/{id} /編集を閲覧と編集の両方に使用している理由が不思議でした。

+0

補遺:実際に同じページで表示して編集したい場合は、フォームにajaxifyを考慮する必要があります。 – Spoike

0

Ajaxフォームが送信されますか?

は、ユーザーのヒットを更新すると、あなたは時代遅れのビューを取得することを言っているMS MVC form AJAXifying techniquesASP.NET MVC Tip #5 - Submitting an AJAX Form with jQuery

+1

フォームをAJAX化することは、ユーザーがF5を押すときに役立ちません。 –

+0

あなたのフォームが現在の状態を把握するのに十分なほど巧妙であるかどうかによりますか? – cletus

+0

しかし、フォームが現在の状態を把握するのに十分なほど巧妙であれば、AJAXもなくても機能します。私はFrank Kruegerのサンプルコードのほうがはっきりとしたものになると思います。 –

0

を参照してください。これから私はあなたのGETアクションがPOSTアクションからTempDataの中に格納されたオブジェクトを使用していると仮定します。この場合、回避策として、TempDataの代わりにSessionを使用してPOSTアクションの結果を格納する方法があります。

0

投稿フォームが記述したとおりに機能するためには、データベースからデータを読み込み、フォームのフィールドをあらかじめ入力する必要があります。問題のURLを最初に入力するときから、これを行う必要があります。

投稿すると、検証後に値をデータベースに保存する必要があります。これにより、ラウンドトリップループが完了します。

ページが空白の「新しいレコード」ページである場合は、正しいですが、失敗した検証では1回だけラウンドトリップします。 F5では、デザインによって新しい空白のフォームが提供されます。

1

あなたが本当には、表示と編集のための同じページを持ちたい、あなたが最後に更新された日付をINCLUD隠しフィールドを保つことができる同時実行を処理する必要がある場合。したがって、フローは次のようになります。

  1. User1がデータを送信します。
  2. 同じページは、日付要素で表示されますが(date1と言うことができます)。
  3. User2がこのページを送信します。
  4. User1が再度送信します。このアクションは、date1と実際の更新日を比較します。
  5. これらは異なりますので、アクションは更新してユーザーに通知してはなりません。

これは単なる別のオプションです。

+0

バージョン番号は日付よりも良いでしょう – Charlie

8

投稿が完了した後に再び編集ビューに戻らないという主要な答えには同意しますが、なぜリフレッシュを押すとフォームが再ポストされるのかという問題には答えません。

「ブラウザでリフレッシュして別の投稿を表示する」問題の解決方法は次のとおりです。あなたは、このやっている瞬間


[AcceptVerbs(HttpVerbs.Post)] // <-- This action will be used for POSTs 
EditProduct(string data1, string data2) 
{ 
    // Handle Data, save to DB 
    // Do some work 
    return RedirectToAction("EditProduct"); // <-- Redirect to a GET Action 
} 

[AcceptVerbs(HttpVerbs.Get)] // <-- This action will be used for GETs 
EditProduct() 
{ 

    return View("EditProduct"); // <-- Render the view from the GET action 
}        //  So when you refresh it will refresh the GET 

キーポイントは返さない、次のとおりです。

[AcceptVerbs(HttpVerbs.Post)] // <-- this action will be used for POSTs 
EditProduct(string data1, string data2) 
{ 
    // Handle Data, save to DB 
    // Do some work 
    return View("EditProduct"); // <-- You are rendering the view from 
}        //  A post action - this is bad! 

をあなたが実際にこれを行う必要がありますPOSTに応答して表示する。そうしないと、ブラウザの最後のリクエストがPOSTリクエストであったため、ブラウザのリフレッシュを再実行する。むしろ、あなたのポストアクションが終了したら、RedirectToAction()を使って "GET"アクションにリダイレクトしてください。 GETアクションはビューを返します。これは、ブラウザー内の前の要求がGET要求であったことを意味し、リフレッシュを押すと、再度取得し、再ポストしません。 MVCを使い始めたときも同じエラーが出ました。

+1

POSTが成功した後にGETにリダイレクトすることは常に良い考えです。しかし、ModelStateが無効な場合は、GET EditProductメソッドを呼び出すだけで問題ありません。 EditProductメソッドを呼び出すとビューが再構築され、MVCフレームワークはModelStateの値がポストされたモデルデータを上書きします。 –

+0

本当によく説明されて...おめでとう! :) –

関連する問題