Когда использовать TempData vs Session в ASP.Net MVC

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

В настоящее время единственное, что я использую для хранения сеанса, - это сохранение текущего зарегистрированного пользователя. Мой сайт прост. В этом примере рассмотрим три объекта домена: 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?

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

TempData​​strong > Vs Сессия

TempData​​STRONG >

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

    Пример:

    TempData.Keep(), TempData.Keep( "EmpName" )

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

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

Сеанс:

  • Сессия может хранить данные гораздо дольше, пока сеанс пользователя не истечет.
  • Сессия истекает после истечения времени ожидания сеанса.
  • Он действителен для всех запросов.
  • N/A
  • Вариация сеанса хранится в объекте SessionStateItemCollection (который отображается через свойство HttpContext.Session страницы).
  • Он используется для хранения данных продолжительной жизни, таких как идентификатор пользователя, идентификатор роли и т.д., который требуется на протяжении всего сеанса пользователя.

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

Ответ 5

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

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

Ответ 7

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

Использовать сеанс, когда необходимы данные для всего приложения