2009-09-30 3 views
57

Я пытаюсь получить структуру MVC, так что несите меня.Когда использовать TempData vs Session в ASP.Net MVC

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

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

Это, как я в настоящее время установки Добавить действия, но он не работает:

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?

+0

Какой тип TempDataKeys, просто класс? Или перечисление? – Anon343224user

ответ

83

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

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

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

+0

Мне не нужны роли, у всех есть тот же доступ после входа в систему. плохо мои исследования по IsAuthenticated, хотя, спасибо – scottm

+1

Не является ли механизм аутентификации основанным на cookie и не может ли он быть украден подобным образом? – IsmailS

+2

@ Ismail, да, используется файл cookie (по умолчанию). Нет, он не может быть украден подобным образом. Аутентификация предназначена для обеспечения безопасности. Сессия - нет. Это две разные вещи. –

4

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

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

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

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

+0

Есть два комментария, которые описывают, что не работает для меня. Я догадался, что могу передать объект и не возвращать его из базы данных, но теперь, когда я думаю об этом, это, вероятно, добавит много проблем параллелизма. – scottm

0

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

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

16

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

+1

Я понимаю это. Я помещал объект собрания в TempData в методе GET, а затем, когда пользователи отправляют форму, я должен снова получить его из TempData, верно? – scottm

+3

Нет, вы не можете рассчитывать. TempData предназначен только для перенаправления. Если вы установите TempData в GET, ваша страница сделает AJAX-вызов, тогда пользовательские POST-файлы, TempData * исчезнут. * –

+1

«Нет, вы не можете рассчитывать». -> «Нет, вы не можете рассчитывать на это». См. Ссылку в моем ответе для получения дополнительной информации о TempData и перенаправлениях. –

0

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

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

3

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

TempData Vs Сессия

TempData

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

    Пример:

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

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

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

Сессия:

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

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

Смежные вопросы