Подтвердить что ты не робот

Существует ли наилучшая практика и рекомендуемая альтернатива переменным сеанса в MVC

Хорошо, сначала прежде чем кто-либо попытается сделать вывод, что это "дублирующий" вопрос; Я рассмотрел большинство сообщений о SO по поводу похожих вопросов, но даже в сочетании всего, что было сказано, я все еще несколько дилемма относительно окончательного или, может быть, я должен сказать единодушное согласие по этому вопросу.

Я могу сказать, что у меня (на основе сообщений) окончательно определено, что ответ основан на объеме требования. Но даже с учетом этого мнения кажутся слишком разнообразными для меня, чтобы принять решение о том, как я должен справиться с этим.

Мое непосредственное требование состоит в том, что мне нужно перенести переменные данные из 1 контроллера во многие виды. Более конкретно, у меня есть контроллер и соответствующее представление, которое обрабатывает количество элементов корзины покупок, и я хотел бы сохранить эти данные в нескольких представлениях. Я думаю, что просмотр _layout является наиболее логичным выбором для этого.

Теперь я успешно выполнил эту задачу, присвоив значение переменной Session, которая извлекается из моего представления _layout; поэтому даже когда пользователь должен был перемещаться по любому месту внутри сайта, количество элементов в корзине покупок будет сохраняться до тех пор, пока они не покинут сайт или не проведут проверку; в этом случае переменная будет очищена в коде.

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

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

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

Если есть другая хорошо подходящая альтернатива переменной Session (которая работает для меня), я хотел бы знать, что это такое.

2 сообщения, которые кажутся противоречивыми в усилиях по предоставлению лучших рекомендаций, оставляют меня немного смущенным.

Минусы: Является ли хорошей практикой избегать использования состояния сеанса в ASP.NET MVC? Если да, то почему и как?

Плюсы: Все еще хорошо использовать переменные сеанса в ASP.NET mvc, или есть лучшая альтернатива для некоторых вещей (например, тележка)

Кажется, что этот вопрос (хотя и представленный во многих разных вариантах) не имеет окончательного ответа, который я могу заключить.

Если есть более предпочтительный способ сделать это без излишнего, то это ответ, который я ищу.

Я где-то читал использование фильтров MVC в тандеме с секцией запуска приложения Global.ascx, но это не похоже на переменные, установленные на уровне контроллера, насколько это возможно, статические переменные.

Может кто-нибудь может сквош (из-за отсутствия лучшего слова) много разных мнений по этой теме и, возможно, дать более окончательный ответ на вопрос? Я уверен, что разные мнения имеют свое место, и я не пытаюсь их дискредитировать. Но иметь окончательный и, возможно, единодушный ответ был бы лучше; затем я мог бы сортировать другие сообщения, чтобы определить, что лучше для моего приложения.

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

Спасибо

=============================================== ============

ОБНОВЛЕННЫЙ ОТВЕТ НА ПРЕДОСТАВЛЯЕМЫЕ ОТВЕТЫ

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

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

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

Поэтому сохранение оптимизированной и чистой БД (что "для меня" имеет равную значимость) потребовало бы выполнения задачи обслуживания автоматически истекать эти записи на основе установленного порога времени для учета этих обстоятельств. Хотя задача обслуживания не является неоспоримым вариантом, я все же думаю, что это добавляет немного больше работы для задачи просто для намеренной цели использования в качестве временного хранилища.

Тем не менее, я уважаю рекомендацию Тима и считаю, что она заслуживает заслуги в том, что касается моего первоначального мнения; что база данных не будет являться жизнеспособным вариантом для хранения временных данных; поэтому я считаю, что компромисс должен состоять в том, чтобы хранить данные в базе данных (учитывая сценарий корзины покупок или аналогичный), возможно, после проверки. Таким образом, как вы ранее заявляли, данные могут постоянно отслеживаться при последующих посещениях, поэтому у вас есть запись транзакций. Но что более важно, именно данные этих транзакций имеют реальную актуальность для сохранения базы данных.

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

НО... Я думаю, что Эрик подобрал точку с эффектом Даннинга-Крюгера. Хотя, из содержания и объяснений предлагаемых ответов, приведенных здесь; Я серьезно сомневаюсь, что опыт любого из тех, кто отреагировал, в какой-то степени сомнительный. Тем не менее, я склонен согласиться с фактом получения единодушного мнения, может быть несколько более обоснованным, чем ожидалось с моей стороны.

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

=============================================== ===

Резюме на основе отзывов:

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

  • Кэширование предпочтительнее по сравнению с переменными сеанса, но опять же не обязательно является "лучшим" масштабируемым параметром из-за, среди прочего, возможных сложностей синхронизации в средах фермы веб-серверов, как указывалось ранее. Но, тем не менее, вариант.

  • Хранилище базы данных является масштабируемым, но с целью назначения временного энергозависимого хранилища, вероятно, не самый элегантный вариант с точки зрения базы данных, поскольку это потребует периодической очистки. Лично, имея прочную основу в концепциях базы данных ранее в моей карьере, это, вероятно, не будет тем, с чем, вероятно, согласятся многие разработчики; но использование базы данных для этой цели может быть достаточным для веб-разработки с точки зрения программистов; однако с точки зрения развития DAL и БД это (для меня) имеет потенциал для мандата дополнительной задачи БД для обеспечения эффективного бэкэнд.

  • Файлы cookie кажутся хорошим вариантом с комбинированными "желательными" элементами переменных сеанса и кэширования.

=============================================== ===

ЗАКЛЮЧЕНИЕ

Основываясь на ответах; Я думаю, что COOKIES и CACHING, по-видимому, обычно представляют собой хорошо продуманные предложения по наилучшей практике по всем направлениям в сочетании с хранением базы данных, когда после этого требуется постоянное сохранение; как потенциально хорошие кандидаты на масштабируемость представленных.

Окончательный выбор между 2, по-видимому, будет основываться на количестве и типе данных, требующих хранения (например, чувствительных и нечувствительных и независимо от того, есть ли какая-либо проблема, что клиент может изменить данные на их конце); в дополнение к специальным соображениям для COOKIES в том, что они могут быть отключены клиентами.

Очевидно, что ни один из них не подходит для всех решений, как это четко указано и завершено из полученных ответов, а с точки зрения масштабируемости; Возможно, я ошибаюсь, но они кажутся лучшими.

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

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

Спасибо, ребята!

4b9b3361

Ответ 1

Вы никогда не получите единодушное мнение ни о чем в какой-либо большой группе людей. Это просто человеческая природа. Часть этого проистекает из эффекта Дуннинга-Крюгера, в котором говорится, что чем меньше кто-то знает о предмете, тем больше вероятность того, что они будут ценить свой опыт в этой теме. Другими словами, многие люди думают, что они что-то знают, но только потому, что не знают, что они этого не знают. Часть этого просто состоит в том, что люди имеют разные переживания, а некоторые не обнаружили проблем с сеансом, в то время как другие в разных ситуациях или наоборот...

Итак, чтобы сделать резервную копию ваших исследований, которые предполагают, что ответ в значительной степени зависит от требований, нам нужно понять, каковы ваши требования. Если это должен быть сайт с высоким трафиком, с серверами с балансировкой нагрузки в веб-ферме, тогда оставайтесь как можно дальше от сеанса. Конечно, возможно совместное использование сеанса различными способами в среде фермы серверов (сеансовый сервер, распространение кеш-сервера и т.д.), Но избежать сеанса почти всегда будет быстрее, если вы сможете ему помочь.

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

Другая проблема заключается в том, что сеанс сериализуется. Другими словами, IIS предотвращает одновременную запись в поток более одного потока, и это часто делает это, блокируя сеанс, когда поток работает, если он не отключил запись в режиме блокировки сеанса. В некоторых случаях это может вызвать серьезные проблемы, а в других - низкую производительность. Вы можете смягчить это, отметив различные методы атрибутом сеанса только для чтения, если вы не собираетесь его изменять в этом методе.

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

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

Ответ 2

Когда

Базы данных сильно оптимизированы. Простое значение, такое как подсчет корзины покупок, является хорошим кандидатом для кэширования по базе данных и (надеюсь) дешевым для вычисления. Это может быть не проблема.

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

Cache отлично подходит для значений на уровне всего сайта или значений, специфичных для пользователя, с уникальными ключами. Однако синхронизация кешей на нескольких веб-серверах может быть затруднена. Состояние сеанса процесса остается синхронизированным, поскольку оно хранится в одном месте (база данных или сервер состояния).

Конечно, есть много сторонних кеширующих альтернатив с различными параметрами, чтобы синхронизировать их.

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

Производительность

Если вы используете из состояния сеанса процесса (например, в среде с балансировкой нагрузки и/или чтобы сделать сеанс более долговечным), он попадет в базу данных или вызовет внепроцессное обслуживание, но вызов относительно дешев, если вы не используете сериализация графов больших объектов.

Сессия загружается один раз за запрос. Последующий доступ для чтения очень быстрый.

Запись на сеанс может нанести ущерб производительности, даже если загрузка отсутствует. Зачем? большинство современных приложений используют асинхронные вызовы, и когда несколько асинхронных вызовов попадают в обработчик HTTP (страница, контроллер и т.д.), который читает/записывает сеанс, ASP.Net блокирует сеанс для сериализации доступа. Чтобы этого избежать, вы можете украсить свои контроллеры с помощью [SessionState( SessionStateBehavior.ReadOnly )]

Дизайн

Теперь я успешно выполнил эту задачу, присвоив значение к переменной сеанса, которая извлекается из моего представления _layout;

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

Я где-то читал использование фильтров MVC в тандеме с Global.ascx раздел запуска приложения, но это не кажется подходящим для переменных, установленных на уровне контроллера, насколько это возможно, статических переменные.

Статические переменные имеют совершенно законное применение, но вы должны понимать их полностью или подвергать серьезным проблемам.

См. мои ответы, относящиеся к статическим переменным в ASP.Net:

Ответ 3

Альтернатива сеанса в разных перспективах: -

Когда вы сохраняете что-то в сеансе, это прерывает основное правило в ASP.NET MVC. Эти варианты можно использовать в качестве альтернативы сеансу.

Если ваш сеанс asp.net(MVC) делает бокс-распаковку на объекте, он немного загружается на сервер. Попробуйте эту идею

  • Кэширование: - Сохранение списка или что-то вроде больших данных в сеансе лучше всего подходит для кэширования. У вас есть контроль, когда вы хотите, чтобы он истекал, а не сеанс пользователя.

  • Если ваше приложение зависит от данных JSON/Ajax, вы можете использовать некоторые функции, предоставляемые в html5 (например, WebSQL, IndexDB). он не будет использовать файл cookie, чтобы вы могли сохранить некоторую рабочую нагрузку на сервере.