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;
}
}
Action方法如下所示:
[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开发Web服务器上进行测试。 没有Ajax调用,我从主页面中删除了所有的Html.RenderAction调用。 我可以看到TempData在GetAuditedMessages中每次请求只访问一次,并且只在OnResultExecuting中存储一次。 没有什么会覆盖数据。 会话状态是允许的。
代码稍微简化了一点。 我们还使用防伪令牌,自定义过滤器进行授权和动作选择,但不应影响TempData行为。
我不明白。 我在测试应用程序之前使用了TempData,它工作正常。
我在代码中看到的问题是,您试图从控制器的构造函数中的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;
}
}
我认为这是发生了什么:
在CancelEdit中,你的RedirectToAction被返回,框架重定向到“Detail”。 在你的Detail方法中,ActionExecuting触发,但是它的filterContext.Result不是你的RedirectToAction结果 - 这是一个新的结果(实际上,目前还没有结果)。
你需要检查“filterContext.Result是RedirectToRouteResult”吗? 看起来您只会在执行重定向之前添加这些消息。
链接地址: http://www.djcxy.com/p/74427.html