web-dev-qa-db-ja.com

異なるコントローラーアクションメソッド間でデータを渡す

ASP.NET MVC 4を使用しています。あるコントローラーから別のコントローラーにデータを渡そうとしています。これは正しくありません。これが可能かどうかわかりませんか?

データを渡すソースアクションメソッドを次に示します。

public class ServerController : Controller
{
     [HttpPost]
     public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel)
     {
          XDocument updatedResultsDocument = myService.UpdateApplicationPools();

          // Redirect to ApplicationPool controller and pass
          // updatedResultsDocument to be used in UpdateConfirmation action method
     }
}

このコントローラーのこのアクションメソッドに渡す必要があります。

public class ApplicationPoolController : Controller
{
     public ActionResult UpdateConfirmation(XDocument xDocument)
     {
          // Will add implementation code

          return View();
     }
}

ApplicationPoolsUpdateアクションメソッドで次のことを試しましたが、機能しません。

return RedirectToAction("UpdateConfirmation", "ApplicationPool", new { xDocument = updatedResultsDocument });

return RedirectToAction("UpdateConfirmation", new { controller = "ApplicationPool", xDocument = updatedResultsDocument });

どうすればこれを達成できますか?

68
Brendan Vogt

HTTPおよびリダイレクト

最初に、ASP.NET MVCの仕組みを復習しましょう。

  1. HTTP要求が着信すると、一連のルートと照合されます。ルートがリクエストに一致する場合、ルートに対応するコントローラーアクションが呼び出されます。
  2. アクションメソッドを呼び出す前に、ASP.NET MVCはモデルバインディングを実行します。モデルバインディングは、HTTPリクエストのコンテンツ(基本的には単なるテキスト)をアクションメソッドの厳密に型指定された引数にマッピングするプロセスです

また、リダイレクトとは何かを思い出してみましょう。

HTTPリダイレクトは、Webサーバーがクライアントに送信できる応答であり、異なるURLで要求されたコンテンツを探すようにクライアントに指示します。新しいURLは、Webサーバーがクライアントに返すLocationヘッダーに含まれています。 ASP.NET MVCでは、アクションからRedirectResultを返すことでHTTPリダイレクトを行います。

データの受け渡し

文字列や整数などの単純な値を渡すだけの場合は、LocationヘッダーのURLでクエリパラメーターとして渡すことができます。これは、次のようなものを使用した場合に起こることです

return RedirectToAction("ActionName", "Controller", new { arg = updatedResultsDocument });

他の人が示唆したように

これが機能しない理由は、XDocumentが潜在的に非常に複雑なオブジェクトだからです。 ASP.NET MVCフレームワークが、URLに収まるものにドキュメントをシリアル化し、URL値からXDocumentアクションパラメーターにモデルバインドするための簡単な方法はありません。

一般に、クライアントが次のリクエストでサーバーにドキュメントを返すためにクライアントにドキュメントを渡すことは非常に脆弱な手順です。あらゆる種類のシリアライゼーションとデシリアライゼーションが必要であり、あらゆる種類の問題が発生する可能性があります。ドキュメントが大きい場合、帯域幅のかなりの浪費になる可能性があり、アプリケーションのパフォーマンスに深刻な影響を与える可能性があります。

代わりに、サーバー上にドキュメントを保持し、クライアントに識別子を渡すことです。その後、クライアントは次のリクエストとともに識別子を渡し、サーバーはこの識別子を使用してドキュメントを取得します。

次のリクエストで取得するためのデータの保存

さて、質問は今、サーバーはその間にドキュメントをどこに保存するのでしょうか?まあ、それはあなたが決めることであり、最良の選択はあなたの特定のシナリオに依存します。このドキュメントを長期的に利用できるようにする必要がある場合は、ディスクまたはデータベースに保存することをお勧めします。一時的な情報のみが含まれている場合は、Webサーバーのメモリ、ASP.NETキャッシュ、またはSession(またはTempData、最終的にはSessionとほぼ同じ)に保持するのが適切なソリューションです。いずれにしても、後でドキュメントを取得できるようにするキーの下にドキュメントを保存します。

int documentId = _myDocumentRepository.Save(updatedResultsDocument);

そして、そのキーをクライアントに返します:

return RedirectToAction("UpdateConfirmation", "ApplicationPoolController ", new { id = documentId });

ドキュメントを取得する場合は、キーに基づいて取得するだけです。

 public ActionResult UpdateConfirmation(int id)
 {
      XDocument doc = _myDocumentRepository.GetById(id);

      ConfirmationModel model = new ConfirmationModel(doc);

      return View(model);
 }
64
Rune

ASP.NET MVC TempData を使用してみましたか?

ASP.NET MVC TempDataディクショナリは、コントローラーアクション間でデータを共有するために使用されます。 TempDataの値は、読み取られるか、現在のユーザーのセッションがタイムアウトするまで保持されます。 TempDataでのデータの永続化は、単一の要求を超えて値が必要なリダイレクトなどのシナリオで役立ちます。

コードは次のようになります。

[HttpPost]
public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel)
{
    XDocument updatedResultsDocument = myService.UpdateApplicationPools();
    TempData["doc"] = updatedResultsDocument;
    return RedirectToAction("UpdateConfirmation");
}

そして、ApplicationPoolControllerで:

public ActionResult UpdateConfirmation()
{
    if (TempData["doc"] != null)
    {
        XDocument updatedResultsDocument = (XDocument) TempData["doc"];
            ...
        return View();
    }
}
60
user1073075

個人的に私はTempDataを使用したくないが、 ASPのコントローラ間で情報を渡す.Net-MVC

常にそれを明示的かつ期待どおりにする方法を見つける必要があります。

11
L-Four

TempDataの代わりにこれを使用することを好みます

public class Home1Controller : Controller 
{
    [HttpPost]
    public ActionResult CheckBox(string date)
    {
        return RedirectToAction("ActionName", "Home2", new { Date =date });
    }
}

そして別のcontroller Action

public class Home2Controller : Controller 
{
    [HttpPost]
    Public ActionResult ActionName(string Date)
    {
       // do whatever with Date
       return View();
    }
}

遅すぎますが、将来的には誰にとっても役立つことを願っています

2
Amgad Mohamed