TempData始终为空

时间:2011-01-13 14:26:26

标签: asp.net-mvc asp.net-mvc-2 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,它工作正常。

3 个答案:

答案 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"  />