TempData is always empty

I want to use TempData to store messages between Post and subsequent forwarding, but TempData is always empty.

I have a BaseContoller offering some infrastructure for transmitting TempData. The simplified code looks like this:

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;
  }
}

The action method looks like this:

  [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});
  }

The application is being tested on the VS Development web server. There are no Ajax calls, and I removed all the Html.RenderAction calls from my main page. I see that TempData is accessed only once per request in GetAuditedMessages and saved only once in OnResultExecuting. Nothing overwrites data. Session state is allowed.

The code is a little simplified. We also use the antiforgery token, custom filters for authorization and action selection, but should not affect the behavior of TempData.

. TempData , .

+3
2

, , , 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;
  }
}
+10

, , :

CancelEdit RedirectToAction, "Detail". Detail ActionExecuting, filterContext.Result RedirectToAction - ( , ).

"filterContext.Result - RedirectToRouteResult"? , , .

+1

Source: https://habr.com/ru/post/1785214/


All Articles