TempData не очищается

Я работаю над веб-приложением ASP.NET MVC 3, где я использую TempData для хранения объекта модели в сценарии, когда пользователь не вошел в систему.

Вот поток:

  1. Используйте форму отправки.
  2. Код (специальный фильтр действий) добавляет модель к TempData, перенаправляет на страницу входа в систему.
  3. Пользователь перенаправлен обратно к действию GET, которое считывает TempData и напрямую вызывает действие POST.

После шага 3 я мог подумать, что TempData будет очищена?

Вот код:

[HttpGet]
public ActionResult Foo()
{
    var prefilled = TempData["xxxx"] as MyModel;
    if (prefilled != null)
    {
       return Foo(prefilled);
    }
}

[HttpPost]
[StatefulAuthorize] // handles the tempdata storage and redirect to logon page
public ActionResult Foo(MyModel model)
{
   // saves to db.. etc
}

Я нашел эту статью, в которой говорится:

  1. Элементы удаляются из TempData только в конце запроса, если они были помечены для удаления.
  2. Элементы помечаются для удаления только при чтении.
  3. Элементы можно удалить, вызвав TempData.Keep (ключ).
  4. RedirectResult и RedirectToRouteResult всегда вызывают TempData.Keep ().

Что ж, если читать его с TempData["xxx"], разве это не «прочитанное», и поэтому они должны быть помечены для удаления?

И последнее меня немного беспокоит - так как я делаю перенаправление после POST (P-R-G). Но этого не избежать.

Есть ли способ сказать «брось этот предмет». TempData.Remove? Или я не так делаю?


person RPM1984    schedule 03.10.2011    source источник
comment
Вам нужно выполнить полное перенаправление и не возвращать второй метод действия. Вот почему это не работает.   -  person Buildstarted    schedule 03.10.2011
comment
@BuildStarted - но метод POST выполняет перенаправление после его завершения. Вы не можете выполнить перенаправление на метод POST, разве это не будет GET?   -  person RPM1984    schedule 03.10.2011
comment
Из того, что я читаю на основе ограниченных данных, следует, что вы выполняете получение и перенаправление в коде на сообщение - это StatefulAuthorize не будет вызываться.   -  person Buildstarted    schedule 03.10.2011
comment
@BuildStarted - StatefulAuthorize вызывается в начальном POST, например, когда пользователь не прошел проверку подлинности и пытается отправить форму. Я не хочу (и не ожидаю, что это будет вызвано), когда я вызываю метод вручную. Во всяком случае, Дарин резюмировал мою проблему. Итог - я не думаю, что мне следует использовать TempData, я должен использовать Session.   -  person RPM1984    schedule 03.10.2011


Ответы (4)


Исправлено добавлением TempData.Remove сразу после прочтения.

Не очень рад этому. Я думал, что весь смысл TempData в том, что мне не нужно этого делать.

С таким же успехом можно напрямую использовать сеанс.

person RPM1984    schedule 03.10.2011
comment
Это не способ избавиться от этого. Вы могли бы в значительной степени использовать Session вместо TempData. Единственное преимущество TempData заключается в том, что он управляет данными самостоятельно. Как я уже ответил ранее, Value очищается только тогда, когда Action приводит к 200 (например, ViewResult / ContentResult / JsonResult) во всех других сценариях, точно любые действия, приводящие к коду Http Status 302 (например, RedirectAction), сохранят данные в TempData. Прочтите следующее для получения дополнительной информации: stackoverflow.com/questions/32571599/ - person Kiran Vedula; 15.09.2015

Здесь задействованы 2 HTTP-запроса GET:

  1. Первый запрос отправляется клиентом и сохраняет что-то в TempData.
  2. В конце первого запроса клиент отправляет второй HTTP-запрос для получения страницы входа в систему.

В вашем сценарии нет POST-запроса. Тот факт, что из вашего действия GET Foo вы вызываете действие POST Foo, не означает, что выполняется отдельный запрос (вы все еще находитесь в контексте начального запроса GET). Это всего лишь вызов метода C #, а не отдельный запрос.

Вы сохраняете что-то в TempData во время первого запроса, и эти TempData будут доступны для второго. Таким образом, он будет доступен в действии контроллера, отображающем страницу входа в систему.

Таким образом, вы должны прочитать TempData в действии, отображая страницу входа в систему, если вы хотите удалить TempData.

person Darin Dimitrov    schedule 03.10.2011
comment
Твое право. Но меня это не волнует на странице входа в систему. Я пытаюсь сделать автоматическую публикацию, когда они входят в систему, чтобы им не приходилось повторно отправлять форму. Вот почему я вызываю свое действие POST напрямую (я знаю, что это не отдельный запрос). Так что я думаю, мне не следует использовать TempData, так как это 2 запроса позже, для которых мне нужны данные, а не следующий. - person RPM1984; 03.10.2011

Ниже приведены некоторые ключевые моменты, на которые следует обратить внимание при использовании данных Temp.

1) Доступ для чтения к временным данным не удаляет элементы из словаря сразу, а только отмечает их для удаления.

2) Временные данные не всегда удаляют элемент, к которому был осуществлен доступ. Он удаляет элемент только тогда, когда действие приводит к появлению кода состояния Http 200 (ViewResult / JsonResult / ContentResult и т. Д.).

3) В случае действий, которые приводят к Http 302 (например, любые действия перенаправления), данные сохраняются в хранилище, даже когда к ним обращаются.

person Kiran Vedula    schedule 16.05.2015
comment
Ссылаясь на пункт № 3. Как лучше всего очистить эти временные данные, когда я выполняю перенаправление. - person Smac; 08.08.2018

Это не способ избавиться от этого. Вы могли бы в значительной степени использовать Session вместо TempData. Единственное преимущество TempData заключается в том, что он управляет данными самостоятельно.

Как я уже ответил ранее, Value очищается только тогда, когда Action приводит к 200 (например, ViewResult / ContentResult / JsonResult) во всех других сценариях, точно любые действия, приводящие к коду Http Status 302 (например, RedirectAction), сохранят данные в TempData.

Прочтите следующее для получения более подробной информации

ASP.NET TempData не очищается даже после их чтения

person Kiran Vedula    schedule 14.09.2015