【问题标题】:TempData is not clearing as expectedTempData 未按预期清除
【发布时间】:2011-05-10 16:32:24
【问题描述】:

我正在开发一个使用 ASP.NET 4.0 和 MVC 2.0 的应用程序。如果它以任何方式相关,我正在使用 VS2010。

我遇到了 TempData 的复杂情况。我没有编写原始代码,但它无法正常工作,我正在尝试修复它。我没有很多使用 TempData 和 ViewData 的经验。

我有一个索引操作如下(伪代码):

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 为真,视图会发出一个表单并在其前面加上一条成功消息。如果存在,它也会在 TempData["Message"] 中发出消息。

当我第一次访问该页面时,我得到的只是表格。我输入无效的表单数据并提交它......我得到了以错误消息开头的表单,如预期的那样。 (我知道这里的设计很糟糕,因为它没有重定向......而且你在刷新等方面的用户体验很差,但我还不担心)这一切都很棒。

问题在我使用 VALID 表单数据时出现。如果我提交有效的表单数据,我会按预期返回以成功消息开头的页面,但如果我刷新页面,成功消息仍然存在。事实上,如果我去网站的一个完全不同的部分并导航回来,成功的信息仍然存在。由于某种原因,在重定向和读取之后,临时数据仍然存在。既有重定向又有读取……临时数据现在不应该清楚了吗?

我有理由确定我导航到的其他地方没有出于任何原因设置 TempData["Success"],但可以确定我已经导航到 Google 之类的东西,并直接返回到 URL这个页面,它似乎仍然填充了 TempData["Success"]。

很明显,要么我不清楚 TempData 应该如何运作(不足为奇),要么发生了我根本没有经验看到的异常情况。

欢迎任何建议!

谢谢, 戴夫

[编辑]

当有成功消息时,视图实际上不会发出表单......它只会发出成功消息。

视图看起来或多或少像这样:

<% 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...
   <% } %>
<% } %>

Francisco 向我指出了一些我没有考虑过的东西……但事实证明,视图模型的构造函数将 Success 设置为 false……所以这并不奇怪。我确定 TempData["Success"] 仍然设置(而不是像愚蠢地重复使用成功设置为 true 的视图模型之类的东西),因为我已经单步执行了代码,并且它不断地进入设置 vm 的 if 语句。 success = true,即使在刷新之后也是如此。

【问题讨论】:

  • 您确定没有清除临时数据吗?即您是否检查过调试器?你能把代码贴在你在视图中显示成功消息的地方吗?
  • 我已经编辑了原始帖子以包含视图的伪代码。
  • 嗯...我认为缺少一些重要的东西。如果您发出确认消息,您是否传递了更多的值?我试图找到“IndexViewModel”和“ViewModelClass”之间的关系。它们是一样的吗?使用您发布的代码,它应该可以按预期工作。我找不到任何奇怪的地方。如果您可以发布原始代码,将不胜感激。
  • 感谢弗朗西斯科的关注。我不能发布原始代码,因为它是为了工作。我意识到,当我编写伪代码时,我很有可能抽象出问题的根源。只是您说它应该按我期望的方式工作,而不是我描述它实际工作的方式这一事实非常有帮助。我将不得不更深入地挖掘它并开始切割部分,直到它与我的伪代码几乎相同,然后看看会发生什么。
  • 哦,ViewModelClass 和 IndexViewModel 也是一样的。我搞砸了伪编码,给了它们两个不同的名字。我将编辑原始帖子以解决此问题。

标签: asp.net-mvc-2


【解决方案1】:

Microsoft 对 TempData 的行为进行了更改,我们需要在 MVC 2 和 3 中注意这一点。TempData 现在不再在控制器操作周期结束时完全清除。 TempData 现在可以(自动且无需您更改任何内容)持续到其他页面。 TempData 键现在只有在被读取时才会被清除。 此外,如果您使用 RedirectResult 或 RedirectToRouteResult,即使它们被读取,它们也会保留。

这里有更多详细信息:warning-mvc-nets-tempdata-now-persists-across-screens

【讨论】:

  • 我已经以不完整的形式看到了这些信息。我正在读取数据,所以在这方面它应该被清除......我正在使用 RedirectToAction(),它不应该调用 .Keep()......但我会仔细看看这个信息,看看它是否有帮助。谢谢!
  • +1 谢谢,我很惊讶关于这个的文档很少
【解决方案2】:

就像我在评论中所说的那样添加这个。我建议这样做

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

代替

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

... 所以它算作 TempData 读取。很高兴它奏效了。 问候

【讨论】:

    猜你喜欢
    • 2015-02-27
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多