开发者

TempData are always empty

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);
  开发者_Go百科}

  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.


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


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.


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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜