【问题标题】:TempData["message"] isn't reliable-- what am I doing wrong?TempData["message"] 不可靠——我做错了什么?
【发布时间】:2010-05-26 19:00:30
【问题描述】:

我使用TempDate["Message"] 来显示小的更新横幅,因为用户在我的网站上执行如下操作:

[AcceptVerbs(HttpVerbs.Post), Authorize(Roles = "Admins")]
public ActionResult Delete(int id)
{
    _Repo.DeletePage(id); // soft-delete

    TempData["Message"] = "Page deleted!";
    return RedirectToAction("Revisions", "Page", new { id = id });
}

然后在我的母版页中我有这个:

<%-- message box (show it only if it contains a message) --%>
<% string Message = (TempData["Message"] ?? ViewData["Message"]) as string; 

   if(!string.IsNullOrEmpty(Message)){
       %>
       <div id="message"><%:Message %></div>
   <% }

   TempData["Message"] = null; ViewData["Message"] = null; %>

我同时点击了 TempData 和 ViewData,因为我在某处读到 TempData 应该用于重定向,而 ViewData 应该用于其他情况。

问题是:消息通常不会立即显示。有时需要单击或两次单击站点的不同部分才能显示消息。这很奇怪。

有什么想法吗?

【问题讨论】:

  • 你是不是通过ajax请求在其他地方设置TempData?
  • 不,不涉及 ajax(好问题,谢谢!)
  • 这种情况是否发生在任何地方,或者只是在您的开发环境中? (我也经历过类似的事情,但我只是在通过 Visual Studio 网络服务器运行时遇到了问题)。
  • 在我的开发机器(IIS7.5,不是 Cassini)和 beta (IIS6) 上通过 IIS 提供服务时会发生这种情况
  • 代表消失了。对不起各位。如果我得到一个甜蜜的答案,我会开始另一个赏金并奖励给你

标签: asp.net-mvc-2 asp.net-4.0 tempdata


【解决方案1】:

您应该验证您在代码中使用TempData["Message"] 的所有位置。对应于ASP.NET MVC does browser refresh make TempData useless?,您只能读取一次TempData["Message"](另请参阅http://forums.asp.net/p/1528070/3694325.aspx)。在TempData["Message"]的第一次使用期间,TempData["Message"]将从内部TempDataDictionary中删除。

最好只在Page 控制器的Revisions 操作内部使用TempData["Message"],而不是在母版页内部或视图内部。

【讨论】:

  • 我对只读规则很熟悉——我想我会遵守它。您是说不应在视图或母版页中使用临时数据吗?我可以得到它的来源吗?
  • 我的意思是我想你有一些只读规则的影响,例如在多用户环境中可能存在并且可能不那么容易定位。因此,如果您在重定向到Page/Revisions 操作之前使用TempData["Message"],在我看来,在Page/Revisions 内部读取TempData["Message"] 并将其保存在模型中的某个位置以便能够在您的母版页中使用将使您确定您可以完全控制情况并且不会产生奇怪的影响。试着这样做,你会看到奇怪的效果是否仍然存在。
【解决方案2】:

TempData 并非旨在将数据传递给视图,因此为此目的命名为 ViewData。事实上,我根本想不出在视图定义中使用 TempData 的理由......

TempData 的一个非常常见的用法是在您执行重定向时在控制器操作之间传递信息(例如,上面示例中的 Revisions 操作将能够使用您的 TempData["Message"] 变量)。

这是 PRG 编码 MVC 交互(Post-Redirect-Get)的常见做法,因为在执行重定向到 Get 时,您经常需要从初始目标操作传递信息。下面是一个如何在 Get 中使用的示例,我通常只是默认使用新的视图模型,除非已经从 TempData 中的重定向传递了一个:

public ActionResult System() {
   SystemAdminVM model = (SystemAdminVM)TempData["screenData"] ?? new SystemAdminVM();

还有一件事;我看到您在视图中明确清除了 TempData 和 ViewData 字典条目。你不需要这样做,因为到那时他们已经到了生命的尽头......

编码愉快!

【讨论】:

  • 感谢您的帮助!是否有一个标准模式来执行我在这里尝试实现的目标——从许多不同的控制器操作向母版页视图发送消息?
【解决方案3】:

如果您在应该使用 ViewData 的情况下使用 TempData,那么您的应用的行为就是您所期望的。

当控制器进行重定向时,您需要仔细检查您是否将状态反馈存储在 TempData 中。否则,您应该使用 ViewData。

【讨论】:

  • 是的,这就是我正在做的。 TempData 用于重定向,ViewData 否则。
【解决方案4】:

这听起来像是您需要进行几次单元测试来确认您所看到的行为。试着用这个例子作为起点写几个:

http://weblogs.asp.net/leftslipper/archive/2008/04/13/mvc-unit-testing-controller-actions-that-use-tempdata.aspx

【讨论】:

    【解决方案5】:

    如果您为您的应用程序配置了多个工作进程,但会话状态模式为“InProc”,那么您不能使用默认的 TempData 实现,因为会话状态变得不可用。 (见ASP.NET session state and multiple worker processes

    您可以尝试改用 MvcFutures CookieTempDataProvider

    【讨论】:

    • 我不认为我在做网络花园的事情(我会仔细检查),谢谢!
    猜你喜欢
    • 2011-06-04
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 2021-04-14
    • 2021-04-19
    • 2017-03-13
    相关资源
    最近更新 更多