TempData 始终为空
我想使用 TempData 来存储 Post 和后续重定向之间的消息,但 TempData 始终为空。
我有 BaseContoller 提供一些用于传递 TempData 的基础设施。简化的代码如下所示:
public abstract class BaseController : Controller
{
public const string AuditMessagesKey = "AuditMessages";
private List<InformationMessage> _informationMessages = new List<InformationMessage>();
protected BaseController()
{
// I also tried this in overriden Initialize
ViewData[AuditMessagesKey] = GetAuditMessages();
}
protected void AddAuditMessage(InformationMessage message)
{
if (message == null)
return;
_informationMessages.Add(message);
}
protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
if (filterContext.Result is RedirectToRouteResult)
{
// I see that messages are stored into TempData
TempData[AuditMessagesKey] = _informationMessages;
// This also doesn't help
// TempData.Keep(AuditMessagesKey);
}
}
private ICollection<InformationMessage> GetAuditMessages()
{
// TempData are always empty here
var messages = TempData[AuditMessagesKey] as List<InformationMessage>;
if (messages == null)
{
messages = new List<InformationMessage>();
}
return messages;
}
}
操作方法如下所示:
[HttpPost]
public ActionResult CancelEdit(RequestSaveModel model)
{
AddAuditMessage(new InformationMessage
{
Message = String.Format(Messages.RequestEditationCanceled, model.Title),
Severity = MessageSeverity.Information
});
return RedirectToAction("Detail", new { Id = model.Id});
}
应用程序在 VS Development Web 服务器上进行测试。没有 Ajax 调用,并且我从母版页中删除了所有 Html.RenderAction 调用。我可以看到,在 GetAuditedMessages 中每个请求仅访问 TempData 一次,并且在 OnResultExecuting 中仅存储一次。没有任何内容会覆盖数据。允许会话状态。
代码稍微简化了一些。我们还使用防伪令牌、自定义过滤器进行授权和操作选择,但它不应影响 TempData 行为。
我不明白。我之前在测试应用程序中使用过 TempData,效果很好。
I want to use TempData to store messages between Post and followed redirect but TempData are always empty.
I have BaseContoller offering some infrastructure for passing TempData. Simplified code looks like:
public abstract class BaseController : Controller
{
public const string AuditMessagesKey = "AuditMessages";
private List<InformationMessage> _informationMessages = new List<InformationMessage>();
protected BaseController()
{
// I also tried this in overriden Initialize
ViewData[AuditMessagesKey] = GetAuditMessages();
}
protected void AddAuditMessage(InformationMessage message)
{
if (message == null)
return;
_informationMessages.Add(message);
}
protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
if (filterContext.Result is RedirectToRouteResult)
{
// I see that messages are stored into TempData
TempData[AuditMessagesKey] = _informationMessages;
// This also doesn't help
// TempData.Keep(AuditMessagesKey);
}
}
private ICollection<InformationMessage> GetAuditMessages()
{
// TempData are always empty here
var messages = TempData[AuditMessagesKey] as List<InformationMessage>;
if (messages == null)
{
messages = new List<InformationMessage>();
}
return messages;
}
}
Action method looks like:
[HttpPost]
public ActionResult CancelEdit(RequestSaveModel model)
{
AddAuditMessage(new InformationMessage
{
Message = String.Format(Messages.RequestEditationCanceled, model.Title),
Severity = MessageSeverity.Information
});
return RedirectToAction("Detail", new { Id = model.Id});
}
Application is tested on VS Development web server. There are no Ajax calls and I removed all Html.RenderAction calls from my master page. I can see that TempData are accessed only once per request in GetAuditedMessages and stored only once in OnResultExecuting. Nothing overwrites the data. Session state is allowed.
The code is little bit simplified. We are also using antiforgery token, custom filters for authorization and for action selection but it should not affect TempData behavior.
I don't understand it. I used TempData before in test application and it worked fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在代码中看到的问题是,您正在尝试从控制器的构造函数中的 TempData 检索数据 - 这是在数据可用之前。
将对 GetAuditMessages() 的调用移至 OnActionExecuting 方法中,这样就可以访问它了。
The problem I see in your code is that you are trying to retrieve the data from TempData in the controller's constructor - which is before it is available.
Move the call to
GetAuditMessages()
into an OnActionExecuting method, and it will be accessible.我认为这就是正在发生的事情:
在 CancelEdit 中,返回您的 RedirectToAction,并且框架重定向到“Detail”。在您的 Detail 方法中,ActionExecuting 会触发,但它的 filterContext.Result 不是您的 RedirectToAction 结果 - 它是一个新结果(实际上,目前还没有结果)。
您是否需要检查“filterContext.Result is RedirectToRouteResult”?看来您只会在执行重定向之前添加这些消息。
I think this is what's happening:
In CancelEdit, your RedirectToAction is returned, and the framework redirects to "Detail". In your Detail method, the ActionExecuting fires, but it's filterContext.Result is not your RedirectToAction result - it's a new result (actually, no result as of yet).
Do you need the check for "filterContext.Result is RedirectToRouteResult"? It seems that you will only have those messages added before you perform a redirect.
在我的解决方案中,我忘记为我的开发删除 HttpCookies
它只适用于 Https 发布的网站
in my Solution I forgot to remove HttpCookies for my development
it just work on published site in Https