TempData не очищается - PullRequest
       7

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

8 голосов
/ 03 октября 2011

Я работаю над веб-приложением 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"], разве это не «чтение» и поэтому они должны быть помечены для удаления?

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

Есть ли способ, которым я могу сказать "угробить этот предмет". TempData.Remove? Или я делаю это неправильно?

Ответы [ 3 ]

10 голосов
/ 03 октября 2011

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

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

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

7 голосов
/ 03 октября 2011

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

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

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

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

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

3 голосов
/ 16 мая 2015

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

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

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

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

...