TempData всегда пустые - PullRequest
       19

TempData всегда пустые

3 голосов
/ 13 января 2011

Я хочу использовать TempData для хранения сообщений между публикацией и последующим перенаправлением, но 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. Ajax-вызовов нет, и я удалил все вызовы Html.RenderAction со своей главной страницы. Я вижу, что к TempData обращаются только один раз за запрос в GetAuditedMessages и сохраняют только один раз в OnResultExecuting. Ничто не перезаписывает данные. Состояние сеанса разрешено.

Код немного упрощен. Мы также используем токен защиты от подделки, пользовательские фильтры для авторизации и выбора действий, но это не должно влиять на поведение TempData.

Я не понимаю этого. Я использовал TempData ранее в тестовом приложении, и он работал нормально.

Ответы [ 3 ]

10 голосов
/ 16 августа 2011

Проблема, которую я вижу в вашем коде, заключается в том, что вы пытаетесь получить данные из 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 голос
/ 13 января 2011

Я думаю, что это то, что происходит:

В CancelEdit возвращается ваше RedirectToAction, и фреймворк перенаправляется на «Detail». В вашем методе Detail, ActionExecuting запускается, но его filterContext.Result не является вашим результатом RedirectToAction - это новый результат (на самом деле, пока никакого результата).

Вам нужна проверка для "filterContext.Result is RedirectToRouteResult"? Похоже, что вы будете добавлять эти сообщения только до того, как будете выполнять перенаправление.

0 голосов
/ 21 июля 2018

в моем решении я забыл удалить HttpCookies для моей разработки это просто работа на опубликованном сайте в https

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