TempData не очищается, как ожидалось - PullRequest
7 голосов
/ 10 мая 2011

Я работаю над приложением, использующим ASP.NET 4.0 и MVC 2.0. Если это имеет какое-либо отношение, я использую VS2010.

У меня сложности с TempData. Я не писал оригинальный код, но он работает неправильно, и я пытаюсь это исправить. У меня нет большого опыта работы с TempData и ViewData.

У меня есть действие Index следующим образом (псевдокод):

public virtual ActionResult Index()
{
   var vm = new IndexViewModel();

   // some code here to set up the ViewModel

   if (TempData.ContainsKey("Success"))
      vm.Success = true; 

   return View(MVC.Controller.Views.Index, vm);
}

И у меня есть действие POST следующим образом (псевдокод):

[HttpPost]
public virtual ActionResult Index(IndexViewModel vm, List<int> formData)
{
    if (DoSomethingWithData(formData))
    {
       TempData["Success"] = true;
       return RedirectToAction(MVC.Controller.ActionNames.Index);
    }

    TempData["Message"] = "Failed to use formData";

    return View(MVC.Controller.Views.Index, vm);
}

Представление генерирует форму и предваряет ее сообщением об успехе, если vm.Success имеет значение true. Он также отправит сообщение в TempData ["Message"], если оно присутствует.

Когда я впервые захожу на страницу, я получаю только форму. Я ввожу НЕВЕРНЫЕ данные формы и отправляю их ... и получаю форму, предваряющую сообщение об ошибке, как и ожидалось (Я знаю, что здесь плохой дизайн, поскольку он не перенаправляет ... и у вас плохой пользовательский интерфейс с обновлением и т. Д., Но я пока не беспокоюсь об этом) Это все замечательно.

Проблема проявляется , когда я использую данные формы VALID. Если я отправлю действительные данные формы, я получу страницу с предваряющим сообщением об успехе, как и ожидалось, но если я обновлю страницу, сообщение об успехе все еще там. Действительно, если я зайду в совершенно другую часть сайта и вернусь назад, сообщение об успехе все еще там. По какой-то причине после перенаправления и чтения tempdata все еще там. Произошло и перенаправление, и чтение ... разве временные данные не должны быть ясными?

Я достаточно уверен, что в других местах, по которым я перехожу, по какой-либо причине не устанавливается TempData ["Success"], но чтобы быть уверенным, что я перешел к таким вещам, как Google, и вернусь непосредственно к URL для эта страница, и кажется, что TempData ["Success"] заполнена.

Совершенно очевидно, что либо я не совсем понимаю, как должна работать TempData (неудивительно), либо происходит что-то необычное, чего у меня просто нет опыта, чтобы увидеть.

Любой совет приветствуется!

Спасибо, Dave

[EDIT]

Представление фактически не отправляет форму при наличии сообщения об успехе ... оно только выдает сообщение об успехе.

Вид выглядит примерно так:

<% if (TempData.ContainsKey("Message")) { %>
   Emit message...
<% } %>

<% using (Html.BeginForm(MVC.Controller.ActionNames.Index, 
                         MVC.Controller.Name, 
                         FormMethod.Post, 
                         new { id = "form"})) { %>
   <% if (!Model.Success) { %>
      Emit form...
   <% } else { %>
      Emit confirmation message...
   <% } %>
<% } %>

Франциско указал мне на что-то, чего я не учел ... но оказывается, конструктор для модели представления устанавливает Success в false ... так что в этом нет ничего странного. Я точно знаю, что TempData ["Success"] все еще установлен (а не что-то вроде глупого многократного использования модели представления с успехом, установленным в true), потому что я прошел через код, и он постоянно входит в оператор if, где он устанавливает vm. success = true, даже после обновления.

Ответы [ 2 ]

10 голосов
/ 12 мая 2011

Microsoft внесла изменения в поведение TempData, о которых мы должны знать в MVC 2 и 3. Теперь TempData больше не очищается полностью в конце цикла действий контроллера.TempData теперь может (автоматически и без каких-либо изменений) сохраняться на других страницах. Ключи TempData теперь очищаются только в том случае, если они были прочитаны. Кроме того, , если вы используете RedirectResult или RedirectToRouteResult, они сохранятся, даже если они прочитаны.

Здесьболее подробная информация: warning-mvc-nets-tempdata-now-persists-through-screens

7 голосов
/ 12 мая 2011

Просто добавлю это, как я сказал в своем комментарии. Предлагаю сделать

if (TempData["Success"] != null) 
    vm.Success = true;

Вместо

if (TempData.ContainsKey("Success"))
      vm.Success = true; 

... так что это считается чтением TempData. Рад, что это сработало. Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...