2016-11-11 2 views
2

Я пытался передавать данные между контроллерами весь день, но теперь я нахожусь в точке, где, я думаю, я не совсем понял основы.ASP.NET Core MVC: что происходит с запросом на RedirectToAction

На протяжении всей документации ядра ASP .NET они используют слово «запрос». Я был в предположении, что это HttpRequest, созданный клиентом WebServer.

Есть также разные вещи, которые должны быть привязаны к жизни запроса:

  • HttpContext и его HttpContext.Items словарь.
  • Услуги, добавленные с помощью AddScoped через инъекцию зависимости.
  • TempData словарь? (Не уверен, что)

Но при попытке передать данные вокруг, я сделал замечание, что, когда я return RedirectToAction(...); в HttpContext изменения (HttpContext.GetHashCode() имеет другое значение), TempData изменения и услуги, добавленные с помощью AddScoped также являются новые объекты.

Это означает, что на RedirectToAction будет выполнен новый запрос, снова пройдя все этапы конвейера запроса. Мое предположение, однако, состояло в том, что RedirectToAction только продолжает конвейер текущего запроса с другим действием контроллера.

Я также думал, что браузер или любой другой клиент сделал только один запрос и получил один ответ в течение всего этого процесса.

Так что же происходит при вызове RedirectToAction в действии контроллера и возврате результата?

UPDATE: Использование TempData работает, но сначала необходимо настроить TempDataProvider. Например, добавьте services.AddSingleton<ITempDataProvider,SessionStateTempDataProvider>(); в Startup.cs. Спасибо @RonC.

ответ

2

Как уже упоминалось, RedirecToAction заставит браузер сделать новый запрос, и когда этот новый запрос поступит, он создаст совершенно новый HttpContext. Как уже упоминалось, для передачи данных между двумя запросами вы можете использовать строку запроса, сеанс или файлы cookie. Но есть и другой вариант.

TempData
Данные могут быть переданы от одного запроса к другому через TempData коллекции, которая доступна в методе действий контроллера.Коллекция TempData была специально разработана для передачи данных с одного запроса на другой. Красота TempData заключается в том, что время жизни объекта, помещенного в TempData, является ровно одним дополнительным запросом. Таким образом, все, что помещается в TempData в запрос 1, будет там для запроса 2, но затем автоматически удаляется с TempData по завершении запроса 2. Это делает TempData идеальным для передачи данных от одного запроса другому, не раскрывая эту информацию в строке запроса или, возможно, забыть об этом в сеансе и раздувать объект сеанса.

+0

Я действительно пытался использовать TempData для этого, но это не сработало. Но я прочитал что-то о том, что содержимое будет удалено при первом доступе, может быть, проблема? Также я обратился к нему внутри реализации «IActionFilter», а не внутри самого действия контроллера. – FSMaxB

+0

Я еще не работал с фильтрами действий, но это вполне может быть вашей проблемой, если оно удалено при первом доступе (что будет иметь смысл). Поэтому вам, вероятно, следует попробовать, обратившись к нему в следующем запросе в методе действий, не получив вначале его доступ к фильтру действий. Если вам действительно нужно получить доступ к нему в фильтре действий, вы можете повторно добавить его в временные данные или добавить его в коллекцию элементов запроса. Так что он доступен для метода действий. –

+0

Нет, TempData не хранит мои данные, даже если я получаю доступ только один раз. – FSMaxB

1

Невозможно сохранить состояние текущего запроса, потому что ... HTTP является апатридом. Каждый RedirectToAction действительно сообщает браузеру, чтобы сделать еще один HTTP-запрос. Как говорит documentation.

Возвращает ответ HTTP 302 браузеру, что заставляет браузер делать запрос GET указанному действию.

Если вы хотите передать некоторые данные между HTTP-запросами, вам необходимо использовать куки или сеансовый механизм.

+0

'RedirectToAction' также позволяет передавать данные по строке запроса через' routeValues'. – Jasen

+0

@Jasen Но значения маршрута - это те, которые используются для привязки к модели (на мой взгляд). Я думаю, мне придется сериализовать мой объект и сохранить его в сеансе. – FSMaxB

+0

И, похоже, нет документации по версии .NET Core для RedirectToAction, но похоже, что она работает одинаково. – FSMaxB

Смежные вопросы