Когда использовать TempData vs Session в ASP.Net MVC - PullRequest
60 голосов
/ 01 октября 2009

Я пытаюсь освоить MVC Framework, так что терпите меня.

Прямо сейчас, единственное, для чего я использую хранилище сеансов - это сохранение текущего вошедшего в систему пользователя. Мой сайт прост. В этом примере рассмотрим три объекта домена: Person, Meeting и File. Пользователи могут войти в систему и просмотреть профиль собрания «только для участников», а также добавить в него файлы или просмотреть общедоступный «профиль» собрания, если они не вошли в систему.

Итак, из личного профиля собрания, в котором зарегистрированный пользователь, у меня есть ссылка «добавить файлы». Эта ссылка ведет к FileContoller.Add (int meetingId). Из этого действия я получаю собрание, к которому пользователь хочет добавить файлы, используя идентификатор собрания, но после публикации формы мне все еще нужно знать, к какому собранию пользователь добавляет файлы. В этом и заключается мой вопрос: должен ли я пропустить собрание, которое в данный момент взаимодействует с, через TempData, или добавить его в хранилище сеансов?

Вот так у меня сейчас есть настройка Add action, но она не работает:

    public ActionResult Add(int meetingId)
    {
        try
        {
            var meeting = _meetingsRepository.GetById(meetingId);
            ViewData.Model = meeting;
            TempData[TempDataKeys.CurrentMeeting] = meeting; /* add to tempdata here */
        }
        catch (Exception)
        {
            TempData[TempDataKeys.ErrorMessage] = "Unable to add files to this meeting.";
            return RedirectToRoute("MeetingsIndex");
        }

        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Add(FormCollection form)
    {
        var member = Session[SessionStateKeys.Member] as Member;
        var meeting = TempData[TempDataKeys.CurrentMeeting] as Meeting; /* meeting ends up null here */

        if (member == null)
        {
            TempData[TempDataKeys.ErrorMessage] = "You must be logged in to add files to an meeting.";
            return RedirectToRoute("LoginPage");
        }

        if (meeting == null) 
        {
            TempData[TempDataKeys.ErrorMessage] = "An error occurred. No meeting selected.";
            return RedirectToRoute("MeetingsIndex");
        }

            // add files to meeting

        TempData[TempDataKeys.Notification] = "Successfully added.";
        return RedirectToRoute("AddFiles", new {meetingId = meeting.MeetingId});
}

Редактировать:

Основываясь на большинстве ответов, может ли кто-нибудь привести примеры того, какие данные (кроме сообщений) следует хранить в TempData vs Session?

Ответы [ 7 ]

89 голосов
/ 01 октября 2009

TempData - это сеанс, поэтому они не совсем разные. Однако это различие легко понять, поскольку TempData для перенаправлений и только перенаправления . Поэтому, когда вы устанавливаете какое-либо сообщение в TempData и затем перенаправляете, вы правильно используете TempData.

Однако использование Session для любого вида безопасности чрезвычайно опасно. Сессия и членство в ASP.NET полностью разделены. Вы можете «красть» сеансы у других пользователей , и да, люди таким образом атакуют веб-сайты. Поэтому, если вы хотите выборочно прекратить публикацию информации в зависимости от того, вошел ли пользователь в систему, посмотрите на IsAuthenticated , и если вы хотите выборочно показать информацию в зависимости от того, какой тип пользователя вошел в систему, вы используете Роль провайдера . Поскольку GET можно кэшировать, способ only для выборочного разрешения доступа к действию в GET заключается в AuthorizeAttribute.

Обновление В ответ на ваш отредактированный вопрос: у вас уже есть хороший пример использования TempData в вашем вопросе, а именно, возвращение простого сообщения об ошибке после неудачного POST. С точки зрения того, что должно храниться в Session (за пределами "не очень"), я просто думаю о Session как о кеше, специфичном для пользователя. Как и кэш, не относящийся к конкретному пользователю, вы не должны помещать туда секретную информацию. Но это хорошее место для вещей, которые стоит посмотреть. Например, наш Site.Master отображает полное имя пользователя. Это хранится в базе данных, и мы не хотим делать запрос к базе данных для каждой страницы, которую мы обслуживаем. (Установка нашего приложения используется в одной компании, поэтому полное имя пользователя не считается «чувствительным к безопасности».) Поэтому, если вы рассматриваете Session как кеш, который зависит от файла cookie, который есть у пользователя, вы выиграли ' это далеко не так.

17 голосов
/ 01 октября 2009

Поставщик TempData по умолчанию использует сеанс, поэтому различий между ними нет, за исключением того, что данные TempData очищаются в конце следующего запроса. Вам следует использовать TempData, когда данные должны сохраняться только между двумя запросами, предпочтительно вторым является перенаправление, чтобы избежать проблем с другими запросами пользователя - например, из AJAX - для случайного удаления данных. Если данные должны сохраняться дольше, вам следует либо повторно заполнить TempData, либо использовать сеанс напрямую.

4 голосов
/ 22 июня 2017

Вы можете использовать его согласно вашему требованию. Уточнение может быть,

TempData Vs Session

TempData

  1. TempData позволяет нам сохранять данные в течение одного последующего запроса.
  2. ASP.net MVC автоматически истечет значение tempdata, как только последовательный запрос вернет результат (это означает, что он жив только до полной загрузки целевого представления).
  3. Действителен только для текущего и последующего запроса
  4. В TempData есть метод Keep для сохранения значения TempData.

    Пример:

    TempData.Keep (), TempData.Keep («EmpName»)

  5. TempData внутренне сохранил значение в переменной Session.

  6. Он используется для хранения только однократных сообщений, таких как сообщения проверки, сообщения об ошибках и т. Д.

Сессия:

  1. Сеанс может хранить данные гораздо дольше, пока пользовательский сеанс не истечет.
  2. Сессия истекает после истечения времени ожидания сеанса.
  3. Действителен для всех запросов.
  4. N / A * +1046 *
  5. Переменная Session хранится в объекте SessionStateItemCollection (который предоставляется через свойство HttpContext.Session страницы).
  6. Он используется для хранения данных с длительным сроком службы, таких как идентификатор пользователя, идентификатор роли и т. Д., Которые необходимы в течение сеанса пользователя.

TempData и session, оба требовали приведения типов для получения данных и проверки на нулевые значения, чтобы избежать исключения во время выполнения.

4 голосов
/ 01 октября 2009

«Это не работает» не очень описательно, но позвольте мне предложить пару предложений.

Под капотом TempData использует Session для хранения значений. Таким образом, нет большой разницы с точки зрения механизмов хранения или чего-то подобного. Тем не менее, TempData длится только до получения следующего запроса.

Если пользователь делает ajax-запрос между публикациями формы, TempData исчезает. Любой запрос вообще очистит TempData. Так что это действительно только надежно, когда вы делаете ручное перенаправление.

Почему нельзя просто отобразить идентификатор встречи в скрытом поле в форме просмотра? Вы уже добавляете это в модель. Кроме того, добавьте его в свой маршрут в качестве параметра.

0 голосов
/ 28 марта 2014

Значение свойства TempData хранится в состоянии сеанса. Значение TempData сохраняется до тех пор, пока оно не будет прочитано или пока не истечет время ожидания сеанса. Если вы хотите передать данные из одного представления контроллера в другое представление контроллера, вам следует использовать TempData.

Используйте сессию, когда данные нужны для всего приложения

0 голосов
/ 01 октября 2009

Я бы предложил решение MvcContrib: http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/

Если вам не нужен полный MvcContrib, решение - это всего лишь 1 метод + 1 класс, который можно легко получить из источников MvcContrib.

0 голосов
/ 01 октября 2009

Я предпочитаю сохранять такие данные на самой странице. Отобразить MeetingID как скрытый ввод, чтобы он был отправлен обратно в контроллер. Контроллер, обрабатывающий сообщение, может затем передать этот идентификатор собрания обратно в любое представление, которое будет отображаться, так что meetingID в основном будет передаваться столько раз, сколько вам нужно.

Это похоже на разницу между хранением значения в глобальной переменной перед вызовом метода, который будет работать с ней, и передачей значения непосредственно методу.

...