我想使用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,它工作正常。
答案 0 :(得分:10)
我在你的代码中看到的问题是你试图从控制器构造函数中的TempData中检索数据 - 这是在它可用之前。
将呼叫移至GetAuditMessages()
进入OnActionExecuting方法,并且可以访问。
public abstract class BaseController : Controller
{
public const string AuditMessagesKey = "AuditMessages";
private List<InformationMessage> _informationMessages = new List<InformationMessage>();
protected BaseController()
{
// TempData is not available yet
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
ViewData[AuditMessagesKey] = GetAuditMessages();
base.OnActionExecuting(filterContext);
}
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()
{
var messages = TempData[AuditMessagesKey] as List<InformationMessage>;
if (messages == null)
{
messages = new List<InformationMessage>();
}
return messages;
}
}
答案 1 :(得分:1)
我认为这就是发生的事情:
在CancelEdit中,返回RedirectToAction,框架重定向到“Detail”。在你的Detail方法中,ActionExecuting触发,但它的filterContext.Result不是你的RedirectToAction结果 - 它是一个新结果(实际上,还没有结果)。
您是否需要检查“filterContext.Result是RedirectToRouteResult”?您似乎只在执行重定向之前添加了这些消息。
答案 2 :(得分:-1)
在我的解决方案中,我忘了删除HttpCookies进行开发 它只适用于Https中的已发布网站
<httpCookies httpOnlyCookies="true" requireSSL="true" />