Ответ 1
RedirectToAction
возвращает ответ 302 браузеру клиента, и, таким образом, браузер сделает новый запрос GET в URL-адрес в заголовке заголовка ответа, который пришел в браузер.
Если вы пытаетесь передать простую модель с плоским плоским изображением во второй метод действия, вы можете использовать эту перегрузку RedirectToAction
.
protected internal RedirectToRouteResult RedirectToAction(
string actionName,
string controllerName,
object routeValues
)
RedirectToAction
преобразует переданный объект (routeValues) в строку запроса и добавит его к URL-адресу (сгенерированному из первых двух параметров, которые мы передали) и будет вставлять полученный URL-адрес в location ответ.
Предположим, что ваша модель просмотра похожа на это
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);
Этот код отправит 302 ответ браузеру с указанием заголовка местоположения как
Store/Details?StoreId=101&Name=Kroger&Code=KRO
Предполагая, что ваш метод метода Details
имеет тип StoreVm
, значения параметра querystring будут правильно отображаться в свойствах параметра.
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. При таком подходе вы выдадите ответ перенаправления с уникальным идентификатором в querystring, используя тот второй метод действия GET, который может снова запросить ресурс и вернуть что-то в представление.
int newStoreId=101;
return RedirectToAction("Details", "Store", new { storeId=newStoreId} );
Это создаст URL Store/Details?storeId=101
и в вашем приложении GET
, используя файл storeId, вы получите/построите объект 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
}
TempDatah1 >
Следуя PRG pattern, является лучшим решением для обработки этого варианта использования. Но если вы не хотите этого делать и действительно хотите передать некоторые сложные данные через запросы без учета состояния HTTP, вы можете использовать некоторый механизм временного хранения, например TempData
TempData["NewCustomer"] = model;
return RedirectToAction("Index", "Users");
И снова прочитайте его в своем методе действий GET
.
public ActionResult Index()
{
var model=TempData["NewCustomer"] as Customer
return View(model);
}
TempData
использует объект Session
за сценой для хранения данных. Но как только данные будут прочитаны, данные будут завершены.
Рэйчел написал хороший блог post, объяснив, когда использовать TempData/ViewData. Стоит читать.
Использование TempData для передачи данных модели в запрос перенаправления в Asp.Net Core
В ядре Asp.Net вы не можете передавать сложные типы в TempDatastrong > . Вы можете передавать простые типы, такие как string
, int
, Guid
и т.д.
Если вы абсолютно хотите передать объект сложного типа через TempData, у вас есть 2 варианта.
1) Сериализуйте свой объект в строку и передайте это.
Вот пример, использующий Json.NET для сериализации объекта в строке
var s = Newtonsoft.Json.JsonConvert.SerializeObject(createUserVm);
TempData["newuser"] = s;
return RedirectToAction("Index", "Users");
Теперь в вашем методе действий Index
прочитайте это значение из TempData и десериализуйте его в свой объект класса 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) Установите словарь простых типов в TempDatastrong >
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
}