RedirectToAction
クライアント ブラウザに 302 応答を返すため、ブラウザは、ブラウザに届いた応答のロケーション ヘッダー値の URL に対して新しい GET 要求を行います。
単純なリーン フラット ビュー モデルを 2 番目のアクション メソッドに渡そうとしている場合は、メソッドのこのオーバーロードRedirectToAction
を使用できます。
protected internal RedirectToRouteResult RedirectToAction(
string actionName,
string controllerName,
object routeValues
)
はRedirectToAction
、渡されたオブジェクト (routeValues) をクエリ文字列に変換し、それを (渡した最初の 2 つのパラメーターから生成された) url に追加し、結果の url を応答の場所ヘッダーに埋め込みます。
ビューモデルが次のようになっているとしましょう
public class StoreVm
{
public int StoreId { get; set; }
public string Name { get; set; }
public string Code { set; get; }
}
そして、最初のアクションメソッドで、このオブジェクトをこのようにRedirectToAction
メソッドに渡すことができます
var m = new Store { StoreId =101, Name = "Kroger", Code = "KRO"};
return RedirectToAction("Details","Store", m);
このコードは、location ヘッダー値を次のように指定して、302 応答をブラウザーに送信します
Store/Details?StoreId=101&Name=Kroger&Code=KRO
Details
アクション メソッドのパラメーターが typeであると仮定するとStoreVm
、クエリ文字列パラメーターの値はパラメーターのプロパティに適切にマップされます。
public ActionResult Details(StoreVm model)
{
// model.Name & model.Id will have values mapped from the request querystring
// to do : Return something.
}
上記は、小さなフラットリーン ビュー モデルを渡す場合に機能します。ただし、複雑なオブジェクトを渡したい場合は、PRG パターンに従うようにしてください。
PRGパターン
PRG はPOST - REDIRECT - GETの略です。このアプローチでは、クエリ文字列に一意の ID を持つリダイレクト応答を発行します。これを使用して、2 番目の GET アクション メソッドがリソースを再度クエリし、ビューに何かを返すことができます。
int newStoreId=101;
return RedirectToAction("Details", "Store", new { storeId=newStoreId} );
これにより、url が作成され、渡された storeId を使用しStore/Details?storeId=101
て Detailsアクションで、どこか (サービスまたはデータベースのクエリなど) からオブジェクトを取得/構築します。GET
StoreVm
public ActionResult Details(string storeId)
{
// from the storeId value, get the entity/object/resource
var store = yourRepo.GetStore(storeId);
if(store!=null)
{
// Map the the view model
var storeVm = new StoreVm { Id=storeId, Name=store.Name,Code=store.Code};
return View(storeVm);
}
return View("StoreNotFound"); // view to render when we get invalid store id
}
温度データ
PRG パターンに従うことは、このユース ケースを処理するためのより良いソリューションです。しかし、それを望まず、ステートレス HTTPリクエスト間で複雑なデータを渡したい場合は、次のような一時的なストレージ メカニズムを使用できます。TempData
TempData["NewCustomer"] = model;
return RedirectToAction("Index", "Users");
GET
Action メソッドで再度読み取ります。
public ActionResult Index()
{
var model=TempData["NewCustomer"] as Customer
return View(model);
}
TempData
Session
バックグラウンドでオブジェクトを使用してデータを保存します。ただし、データが読み取られると、データは終了します。
Rachel は、 TempData /ViewData をいつ使用するかを説明する素晴らしいブログ投稿を書いています。読む価値があります。
TempData を使用してモデル データを Asp.Net Core のリダイレクト リクエストに渡す
Asp.Net コアでは、複合型を TempData に渡すことはできません。string
、などint
の単純な型を渡すことができます。Guid
TempData を介して複合型オブジェクトを絶対に渡したい場合は、2 つのオプションがあります。
1) オブジェクトを文字列にシリアライズして渡します。
Json.NET を使用してオブジェクトを文字列にシリアル化するサンプルを次に示します。
var s = Newtonsoft.Json.JsonConvert.SerializeObject(createUserVm);
TempData["newuser"] = s;
return RedirectToAction("Index", "Users");
アクション メソッドで、 TempDataIndex
からこの値を読み取り、CreateUserViewModel
クラス オブジェクトに逆シリアル化します。
public IActionResult Index()
{
if (TempData["newuser"] is string s)
{
var newUser = JsonConvert.DeserializeObject<CreateUserViewModel>(s);
// use newUser object now as needed
}
// to do : return something
}
2) 単純型の辞書を TempData に設定します
var d = new Dictionary<string, string>
{
["FullName"] = rvm.FullName,
["Email"] = rvm.Email;
};
TempData["MyModelDict"] = d;
return RedirectToAction("Index", "Users");
そして後で読む
public IActionResult Index()
{
if (TempData["MyModelDict"] is Dictionary<string,string> dict)
{
var name = dict["Name"];
var email = dict["Email"];
}
// to do : return something
}