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

Сессия ASP.Net

Я хочу сохранить "состояние" некоторых действий, которые пользователь выполняет в серии различных веб-форм ASP.Net. Каковы мои предпочтения в отношении сохраняющегося состояния, и каковы преимущества/недостатки каждого решения?

Я использую объекты Session и используя некоторые вспомогательные методы для сильного ввода объектов:

    public static Account GetCurrentAccount(HttpSessionState session)
    {
        return (Account)session[ACCOUNT];
    }

    public static void SetCurrentAccount(Account obj, HttpSessionState session)
    {
        session[ACCOUNT] = obj;
    }

Мне рассказывают многочисленные источники, что "Сессия зла", так что это действительно основная причина этого вопроса. Я хочу знать, что вы думаете о "лучшей практике" и почему.

4b9b3361

Ответ 1

В сеансовом состоянии нет ничего злонамеренного зла.

Есть несколько вещей, которые следует иметь в виду, которые могут вас укусить:

  • Если пользователь нажимает кнопку назад, вы возвращаетесь на предыдущую страницу, но состояние сеанса не возвращается. Таким образом, ваш CurrentAccount может быть не таким, каким он был на странице.
  • Процессы ASP.NET могут быть переработаны IIS. Когда это произойдет, следующий запрос начнет новый процесс. Если вы используете в состоянии сеанса процесса, по умолчанию оно не будет: - (
  • Сессия также может включать тайм-аут с тем же результатом, если пользователь неактивен в течение некоторого времени. Это значение по умолчанию составляет 20 минут, поэтому приятный обед сделает это.
  • Использование состояния сеанса процесса требует, чтобы все объекты, хранящиеся в состоянии сеанса, были сериализованы.
  • Если пользователь открывает второе окно браузера, он будет ожидать второго и отдельного приложения, но состояние сеанса, скорее всего, будет разделено между двумя. Поэтому изменение CurrentAccount в одном окне браузера сделает то же самое в другом.

Ответ 2

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

Использование переменных (ов) сеанса является классическим решением этой проблемы, но оно имеет несколько недостатков. Среди них: (1) большие объемы данных могут использовать серверную ОЗУ, если вы используете управление сеансом inproc, (2) разделение переменных сеанса на нескольких серверах в ферме серверов требует дополнительных соображений и (3) профессионально разработанное приложение должно защищать от истечения срока действия сеанса (не просто передавать переменную сеанса и использовать ее - если срок действия сеанса истек, приведение бросает ошибку). Однако для подавляющего большинства приложений, переменные сессии, бесспорно путь.

Альтернативой является передача каждой информации формы в URL. Основная проблема с этим подходом заключается в том, что вам нужно быть предельно осторожным в отношении "прохождения" информации. Например, если вы собираете информацию на четырех страницах, вам нужно будет собрать информацию в первую очередь, передать ее в URL-адрес на вторую страницу, где вы должны сохранить ее в этом представлении. Затем, вызывая третью страницу, вы будете собирать данные формы со второй страницы плюс переменные viewstate и кодировать как в URL-адресе, так и т.д. Если у вас есть пять или более страниц или если посетитель будет прыгать по сайту, вы У тебя будет настоящий беспорядок на твоих руках. Имейте в виду также, что вся информация должна быть A) должна быть сериализована в строку с безопасным URL-адресом и B) закодирована таким образом, чтобы предотвратить простые хаки на основе URL-адресов (например, если вы поместили цену в ясный текст и передали ее вместе, кто-то может изменить цену). Обратите внимание, что вы можете уменьшить некоторые из этих проблем, создав своего рода "диспетчер сеансов" и попросите его управлять строками URL-адресов для вас, но вы все равно должны быть чрезвычайно чувствительны к тому, что любая данная ссылка может сбить кого-то всю сессию, если он не управляется должным образом.

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

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

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

Чтобы избежать практически всех остальных недостатков сеанса, я рекомендую реализовать объект для хранения ваших данных сеанса, а также некоторые простые функции управления объектами сеанса. Затем создайте их в потомке класса "Страница" и используйте этот дочерний класс страницы для всех ваших страниц. Тогда просто получить доступ к вашим данным сеанса через класс страницы в виде набора строго типизированных значений. Обратите внимание: поля "Объекты" предоставят вам доступ к каждой из ваших "переменных сеанса" строго типизированным способом (например, по одному полю для каждой переменной).

Сообщите мне, если это простая задача для вас или вам нужен образец кода!

Ответ 3

Насколько я знаю, Session - это способ хранения этой информации. Имейте в виду, что состояние сеанса обычно сохраняется в процессе по умолчанию. Если у вас несколько веб-серверов или перезагрузка IIS, вы теряете состояние сеанса. Это можно устранить, используя государственную службу ASP.NET или даже базу данных SQL для хранения сеансов. Это гарантирует, что люди вернутся к своей сессии, даже если они перенаправлены на другой веб-сервер или в случае передела рабочего процесса.

Ответ 4

Что касается "Session is evil"... если бы вы разрабатывали классический ASP, я бы согласился, но ASP.NET/IIS выполняет гораздо лучшую работу.

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

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

Ответ 5

Одной из причин его зловещей репутации является то, что поспешные разработчики злоупотребляют им строковыми литералами в коде UI (а не вспомогательным классом, таким как ваш) в качестве ключей элемента, и в конечном итоге получают большой пакет непроверяемого неразборчивого состояния. Какая-то оболочка - это требование начального уровня для использования незлого сеанса.

Ответ 6

Если вы хотите хранить информацию, доступную глобально в своем веб-приложении, способ сделать это - это атрибут ThreadStatic. Это превращает член static из Class в элемент, который совместно используется текущим потоком, но не с другими потоками. Преимущество ThreadStatic заключается в том, что вам не нужно иметь доступный веб-контекст. Например, если у вас есть обратный конец, который не ссылается на System.Web, но также хочет обмениваться информацией, вы можете установить пользователя id в начале каждого запроса в свойстве ThreadStatic и ссылаться на него в вашей зависимости без необходимости доступа к объекту Session.

Поскольку это static, но только для одного потока, мы гарантируем, что другие одновременные посетители не получают нашу сессию. Это работает, если вы гарантируете, что свойство reset для каждого запроса. Это делает его идеальным компаньоном для файлов cookie.

Ответ 7

Я думаю, что использование объекта Session в этом случае в порядке, но вы должны помнить, что сеанс может истекать, если в течение длительного времени нет активности браузера (HttpSessionState.Timeout определяет, сколько минут оператор сеансового состояния завершает сеанс), поэтому лучше проверить наличие значения до возврата:

public static Account GetCurrentAccount(HttpSessionState session)
{
    if (Session[ACCOUNT]!=null)
        return (Account)Session[ACCOUNT];
    else
        throw new Exception("Can't get current account. Session expired.");
}

Ответ 9

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

Ответ 10

Сессии не являются злыми, они служат важной функции в приложении ASP.NET, обслуживая данные, которые должны совместно использоваться несколькими страницами во время сеанса пользователя. Есть несколько предложений, я бы сказал, что когда-либо можно использовать управление сеансом SQL, и убедитесь, что объекты, которые вы используете в своей коллекции сеансов, являются "сериализуемыми". Лучшей практикой будет использование объекта сеанса, когда вам абсолютно необходимо обмениваться информацией о состоянии на разных страницах и не использовать его, когда вам это не нужно. Информация не будет доступна на стороне клиента. Ключ сеанса хранится либо в файле cookie, либо в строке запроса, либо с использованием других методов в зависимости от того, как он настроен, а затем объекты сеанса доступны в таблице базы данных ( если вы не используете InProc, и в этом случае ваши сеансы будут иметь возможность сдуться во время перезагрузки сайта или будут практически бесполезны в большинстве кластерных сред).

Ответ 11

Сессия как зло: не в ASP.NET, правильно настроена. Да, он идеален, чтобы быть как можно более безграждан, но реальность такова, что вы не можете добраться туда отсюда. Тем не менее, вы можете заставить сеанс вести себя так, чтобы уменьшить его влияние - особенно на сеансы StateServer или базы данных.

Ответ 12

Я думаю, что "зло" происходит из-за использования сеанса. Если вы просто вставляете что-либо и все в него (например, используя глобальные переменные для всего), вы получите плохую производительность и просто беспорядок.

Ответ 13

Все, что вы помещаете в объект сеанса, остается там на время сеанса, если оно не очищено. Плохое управление памятью, хранящейся с использованием inproc и stateserver, заставит вас масштабировать раньше, чем это необходимо. Храните только идентификатор сеанса/пользователя в сеансе и загружайте то, что необходимо в объект кеша по требованию, используя вспомогательный класс. Таким образом, вы можете точно настроить его на всю жизнь в соответствии с тем, как часто эти данные мы использовали. Следующая версия asp.net может иметь распределенный кеш (слухи).

Ответ 14

Что такое сеанс в веб-приложении?

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