ASP.NET MVC - TempData - хороша чи погана практика


96

Я використовую AcceptVerbsметод, описаний у дописі блогу Preview 5 Скотта Гу для роботи із записами форм у ASP.NET MVC:

  • Користувач отримує порожню форму через GET
  • Користувач публікує заповнену форму через POST до тієї самої дії
  • Дія перевіряє дані, робить відповідні дії та перенаправляє на новий вигляд

Тому мені не потрібно користуватися TempData. Тим не менш, я тепер повинен додати крок "підтвердження" до цього процесу, і, схоже, потрібно використовувати TempData.

З якоїсь причини у мене є огида до використання TempData- що це щось, що слід розробити навколо.

Це взагалі поважна проблема, чи я це вигадую?


1
Подумайте про те, щоб зробити крок "підтвердження" діалоговим вікном JavaScript. Менше серверних поїздок, і ви не зіткнетеся з цією проблемою.
ajma

Відповіді:


26

Я вважаю, що тимчасові дані є механізмом сповіщення про забуття та забуття користувача. Чудово нагадати їм про те, що вони нещодавно зробили, але я б також вагався зробити це обов’язковим кроком у якомусь користувацькому процесі. Причиною є те, що якщо вони оновлять сторінку, я вважаю, що її не буде. Ну, я думаю, я також вагаюся використовувати його, оскільки його не дуже чітко визначено, наскільки він надійний.

Цікаво, чи проблема полягає в тому, що ви перенаправляєте дію на іншу сторінку перед кроком підтвердження. Цікаво, чи замість цього після того, як вони вперше надішлють, ви зможете виконати достатньо обробки для створення діалогового вікна підтвердження, а потім поверніть оригінальну сторінку із запитанням підтвердження. Подібно до того, як ви можете виконувати перевірку, за винятком того, що правило перевірки перевіряє, чи був виконаний крок підтвердження (при цьому інтерфейс підтвердження прихований, поки не пройде інша перевірка).


77

Не потрібно мати відрази до TempData ... Але якщо неправильно використовувати їх, це, безумовно, може свідчити про поганий дизайн. Якщо ви використовуєте RESTful URL-адреси, TempData є найкращою практикою для передачі повідомлень з ваших дій POST на ваші дії GET. Розглянемо це:

У вас є форма за адресою URL Products / New. Форма Опублікування до продуктів / Створити, яка перевіряє форму та створює Продукт. Успіх Контролер переспрямовує на URL-адресу Продукти / 1, а при помилці перенаправляє назад на товари / Новий для відображення повідомлень про помилки.

Products / 1 - це лише стандартна дія GET для товару, але ми хотіли б, щоб на екрані з’явилося повідомлення про те, що вставка була успішною. TempData для цього ідеально підходить. Додайте повідомлення до TempData в контролері повідомлень та додайте трохи if логіки у подання та готово.

У разі невдачі я додав значення, введені у formCollection та колекцію повідомлень про помилки, до TempData в Post Action та перенаправляючи до початкових дій Prodcuts / New. Я додав логіку до подання, щоб заповнити вводи форми раніше введеними значеннями, а також будь-якими повідомленнями про помилки. Мені здається приємним і чистим!


Навіщо робити цю додаткову роботу, коли ви можете надсилати повідомлення безпосередньо до Products/New? Яку цінність Products/Createдодає?
mpen

2
@Mark, використовуючи Продукти / Створити, запобігає ситуації, коли користувач виконує дію за допомогою зворотного зворотного зв'язку, а потім при подальшому оновленні (або закладці та поверненні) випадково повторює дію. Детальніше про це читайте en.wikipedia.org/wiki/Post/Redirect/Get
ehdv

2
@ehdv: Але чи справді? У разі успіху він переспрямовує на іншу сторінку, у разі невдачі він повинен відображати помилки форми, і ніяких дій робити не слід, тому шкоди не завдавати. Це лише запобігло б тому настирливому повідомленню "Ви впевнені, що хочете повторно опублікувати", чого я часто хочу. Думаю, це залежить від вашого дизайну, тому я бачу вашу думку.
mpen

31

Думаю, вам добре вагатися перед використанням TempData. TempData зберігається у сеансі, і це може мати для вас наслідки, якщо:

  1. Зараз ви не використовуєте сеанси на своєму сайті
  2. У вас є система, яка повинна масштабуватися до високої пропускної здатності, тобто ви віддаєте перевагу взагалі уникати стану сеансу
  3. Ви не хочете використовувати файли cookie (я не знаю, наскільки добре зараз MVC підтримує сеанси без файлів cookie)

Якщо ваш веб-сайт повинен мати високу доступність, тоді є додаткові міркування щодо застосування стану сеансу, але це все вирішувані проблеми.


16
TempData не потрібно зберігати в сеансі, хоча він є провайдером за замовчуванням - імовірно, тому його немає в методі doc. Існує також постачальник файлів cookie, як приклад того, як написати власного постачальника.
FinnNk

3

У мене є метод GetModel, який спочатку перевіряє наявність TempData ["модель"] і повертає це. В іншому випадку GetModel завантажує відповідні дані з бази даних.

Це економить додаткове навантаження з бази даних, коли у мене є дія, яка потребує повернення іншого подання, яке вимагає однакових даних моделі.


Так, я зіткнувся з цим: (1) перевірити наявність запису, якщо він дійсний, перенаправити на сторінку (2) запис завантаження для відображення для користувача. Тож база даних потрапляє для перевірки та для відображення. Я майже використовую TempData для цього, але мені хотілося перевірити думки. Мені подобається, що ваш метод його містить.
анонімно

В цьому випадку було б краще використовувати належний механізм кешування.
nicodemus13

3

Перевірте безсесійні контролери в MVC3. Виявилося, що використання сеансу перешкоджає паралельному виконанню запитів одного користувача і тим самим призводить до погіршення продуктивності.

Оскільки tempdata використовує сеанс за замовчуванням, ви не зможете використовувати цю функцію. Ви можете перейти на використання файлів cookie для tempdata, але це трохи незручно (принаймні для мене). Однак все-таки чистіше, ніж viewstate, тому, можливо, це не така вже велика угода.


2
Ви маєте рацію щодо безсесійних контролерів, і TempData використовує сеанс. АЛЕ ЗАЧЕКАЙТЕ! Сеанс - це НЕ погано, і ви можете поєднувати та поєднувати Безсесію з контролерами Сесії. Вам дуже потрібні контролери Session_less_, коли ви робите багато викликів AJAX на сервер (із браузера). Коли ви просто натискаєте одну сторінку - раз за разом - .. вам не потрібно бути безсесійним. Насправді це НЕ повинно принести вам жодної вигоди ... тому що ви потрапляєте лише на сервер ОДИН раз. Тож можна поєднувати і поєднувати.
Pure.Krome 03.03.11

2

Чому у вас така огида? Ця річ просто робить свою роботу і робить це добре :)

Якщо вам це не подобається, тому що він не сильно набраний, ви завжди можете зробити обгортку, навколо якої буде наданий вам сильно набраний інтерфейс.


2

Це як використання ViewData, тобто це, мабуть, не є ризиком для безпеки. Але я б скоріше використовував ViewData, ніж TempData. Перевірте тут для порівняння: http://www.squaredroot.com/2007/12/20/mvc-viewdata-vs-tempdata/

Залежно від дизайну, ви завжди можете зберегти користувача / кошик або що завгодно в tempdata в базі даних і просто мати поле "IsReady", яке вказує, заповнене воно чи ні, що робить його розширюваним на потім, якщо ви хочете взяти в пам’ятайте, що люди можуть закрити свій браузер.


2
Примітка: стаття, на яку ви посилаєтесь, була актуальною для свого часу, але є точною лише для MVC1. TempData досить сильно змінилися в MVC2.
mikemanne

@mikemanne, так. Але відповідь з кінця 2008 року. Але, можливо, відповідь слід оновити?
Філіп Екберг,

0

Усі хороші відповіді, чи не бачили ви цього для передачі повідомлень.

TempData та Session не є найкращою ідеєю для архітектур RESTful, оскільки більшість сеансів зберігаються в пам'яті. Отже, коли ви хочете використовувати ферму серверів, сеанс користувачів існуватиме на одному сервері, тоді як їх наступний запит може бути надісланий на інший сервер.

З огляду на це, подивіться на використання TempData для передачі повідомлень сюди.

http://jameschambers.com/2014/06/day-14-bootstrap-alerts-and-mvc-framework-tempdata/

Mabye це може бути адаптоване для використання підходу запиту рядка, якщо використовується лише для переспрямування на іншу сторінку попереджень.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.