TempData 始终为空

发布于 2024-10-12 04:16:47 字数 2012 浏览 4 评论 0原文

我想使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瞳孔里扚悲伤 2024-10-19 04:16:47

我在代码中看到的问题是,您正在尝试从控制器的构造函数中的 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;
  }
}

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.

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;
  }
}
世界和平 2024-10-19 04:16:47

我认为这就是正在发生的事情:

在 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.

南巷近海 2024-10-19 04:16:47

在我的解决方案中,我忘记为我的开发删除 HttpCookies
它只适用于 Https 发布的网站

<httpCookies httpOnlyCookies="true" requireSSL="true"  />

in my Solution I forgot to remove HttpCookies for my development
it just work on published site in Https

<httpCookies httpOnlyCookies="true" requireSSL="true"  />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文