При использовании данных tempdata против сессии в ASP.Net в MVC


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

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

Итак, из личного профиля собрания, с зарегистрированным пользователем у меня есть ссылка" добавить файлы". Эта ссылка ведет к FileContoller.Добавить(инт идентификатором собрания). Из этого действия я получаю собрание, которое пользователь хочет добавить файлы, используя идентификатор собрания, но после публикации формы мне все равно нужно знать, на какое собрание пользователь добавляет файлы. Вот где лежит мой вопрос, Должен ли я передать "текущее взаимодействие с" собранием через 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});
}

Edit:

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

7 60

7 ответов:

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

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

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

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

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

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

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

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

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

TempData Vs сессии

TempData

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

    пример:

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

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

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

сеанс:

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

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

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

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

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

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

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

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