リクエストデータを失うことなくASP.NET MVCでRedirectToActionを実行する方法


123

ASP.NET MVCを使用すると、(フォームの送信など)が必要になる場合がありRedirectToActionます。

このような状況の1つは、フォームの送信後に検証エラーが発生し、フォームにリダイレクトする必要があるが、URLに、送信先のアクションページではなくフォームのURLを反映させたい場合です。

フォームに元のPOSTedデータを含める必要があるため、ユーザーの利便性と検証の目的で、どのようにしてデータをRedirectToAction()?viewDataパラメーターを使用すると、POSTパラメーターがパラメーターに変更されGETます。


これは(同じトピックに関して)似ているが、これとは異なる質問です。とにかく、それでもこの質問に興味がある人には興味があるかもしれません:http
Chris Pietschmann

エラーが発生した場合、なぜ同じビューを返さないのですか?RedirectToActionは通常、モデルが有効な場合に呼び出されます-または何か不足していますか?
niico

回答:


81

解決策は、TempDataプロパティを使用して目的のリクエストコンポーネントを格納することです。

例えば:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

次に、「フォーム」アクションで次のことができます。

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}

1
RedirectToAction(a => a.Form())は、MVCv2を使用してコンパイルできません。MVCv3を使用していますか?
ChrisAnnODell 2010

1
これはMVC1(2008)より前のバージョンです。ラムダは、私が信じているある段階で削除されました(それらを再導入するcodeplexプロジェクトMVCContribがありますが、その段階でヘルパー属性を使用することもできます:stackoverflow.com/questions/1936/…)。mvc2では、RedirectToAction( "Form")、つまり文字列としての名前に移動できるはずですが、検索に行きたがっている場合、MVC 2または3がMVCContribと同様のヘルパー属性を導入したことを大まかに思い出します。
Matt Mitchell

37

TempDataはフォームコレクションをセッション中に保存することに注意してください。その動作が気に入らない場合は、新しいITempDataProviderインターフェイスを実装し、一時データを格納するための他のメカニズムを使用できます。セッション状態の使用があなたに害を与えているという事実(測定とプロファイリングを介して)を知らない限り、私はそれをしません。


13

MVCContribを見て、これを行うことができます:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}

8

tempdataを回避する別の方法があります。私が好きなパターンは、無効なフォームの元のレンダリングと再レンダリングの両方に1つのアクションを作成することです。それはこのようなものになります:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

それが多かれ少なかれパターンです。少し偽物。これにより、フォームのレンダリング、値の再表示(フォームには以前の値が入力されるため)、およびエラーメッセージの表示を処理する1つのビューを作成できます。

このアクションへの投稿時に、そのアクションが有効な場合、別のアクションに制御を移します。

MVCのサポートを構築する際に、.net検証フレームワークでこのパターンを簡単にしようとしています。


私はTempDataも使用していますが、問題は私が理解しているとおりです。Deenoのソリューションでは、ユーザーが無効なデータを投稿した後にページを更新すると、「フォームデータを再送信しますか」という確認が表示されます。MattMitchellが言うようにTempDataソリューションを使用すると、この問題が解消されます。
user10479 2008

涼しい。プレビュー5でも誰かがこの基本的なアイデアに気付いたようです。
Matt Mitchell、

2

リダイレクトされたアクションにデータを渡したい場合、使用できるメソッドは次のとおりです。

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);

0

TempDataは、アクションからアクションへデータを保持するソリューションです。

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.