2010-05-26 61 views
3

我使用TempDate["Message"]作为用户确实在我的网站像这样的事情,以显示小更新横幅:TempData [“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。

问题是:通常邮件不会马上显示出来。有时需要一两次点击才能显示消息。这很奇怪。

任何想法?

+0

您是否在其他地方通过ajax请求设置TempData? – Lester 2010-06-21 20:16:02

+0

不,没有ajax参与(好问题,谢谢!) – 2010-06-21 21:00:28

+0

这是否到处都有,或者仅仅在您的开发环境中? (我曾经历过类似的事情,但是我在运行Visual Studio网络服务器时遇到了问题)。 – Terje 2010-06-27 12:45:06

回答

2

您应该验证代码中使用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中删除。

也许最好只在Revisions控制器的Revisions动作内部使用TempData["Message"],而不是在主控页面内部或视图内部。

+0

我对阅读规则很熟悉 - 我想我会观察它。你是说不应该从视图或母版页使用tempdata?我可以得到一个来源吗? – 2010-06-28 14:23:47

+0

我的意思是说,我认为你有一定的读取规则的效果,例如在多用户环境中可能存在,并且可能不容易定位。因此,如果在重定向到“Page/Revisions”动作之前使用TempData [“Message”]',我认为'Page/Revisions'内的TempData [“Message”]被读取并保存在某个地方在模型中能够在您的母版页中使用将确保您完全控制情况,并且不会有任何奇怪的效果。试着这样做,你会看到奇怪的效果是否仍然存在。 – Oleg 2010-06-28 15:14:00

0

如果您在使用ViewData的地方使用TempData,应用程序的行为就是您期望的行为。

您想仔细检查一下,当控制器执行重定向操作时,您是否将状态反馈存储在TempData 中只有。否则,你应该使用ViewData。

+0

是的,这就是我正在做的。 'TempData'用于重定向,否则'ViewData'。 – 2010-06-21 20:22:16

2

TempData无意将数据传递给视图,因此名称为ViewData。事实上,我想不出从视图定义中使用TempData的原因...

TempData的一个非常常见的用法是当您执行重定向时,控制器操作之间的信息传递(Revisions举个例子,你可以使用你的TempData["Message"]变量)。

这是编程MVC交互(Post-Redirect-Get)的PRG方法中的常见做法,因为您在执行重定向到Get时经常需要传递初始目标操作中的信息。如何这可能是在获取有用的下面是一个例子,我往往只是默认为一个新的视图模型,除非有来自重定向中的TempData已经过去了一个:

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

一两件事;我看到你明确地清除了你的视图中的TempData和ViewData字典条目。你不需要那样做,因为他们在他们的生命尽头跨越反正...

快乐的编码!

+0

感谢您的帮助!有没有一个标准的模式来做我想在这里实现的 - 从许多不同的控制器动作发送消息到主页面视图? – 2010-06-28 15:22:25

0

如果已经配置了多个工作进程为应用程序,但会话状态模式是“InProc方式”,那么你可以不使用默认的TempData实施,因为会话状态变得不可用。 (请参阅ASP.NET session state and multiple worker processes

您可以尝试使用MvcFutures CookieTempDataProvider来代替。

+0

我不认为我在做网络花园的事情(我会仔细检查),谢谢! – 2010-08-16 14:04:04