Спонсор: Microsoft
Опубликован: 24.05.2010 | Уровень: специалист | Доступ: платный
Лекция 9:

Технология ASP.Net : Управление состоянием

Cookie – файлы

Cookie — это текстовая строка, включаемая в запросы и ответы HTTP (Hypertext Transfer Protocol). Файлы cookie используются для сохранения данных о пользователе, посещающем различные страницы веб-узла или возвращающемся на веб-узел спустя некоторое время. В этой статье представлены сведения о файлах cookie.

Одно из главных назначений файлов cookie — предоставлять удобное средство экономии времени. Файлы cookie позволяют сообщить веб-узлу, что пользователь вернулся на конкретную страницу. Например, при обращении к личной веб-странице или при вводе регистрационных данных файлы cookie помогают серверу восстановить сведения, связанные с текущим пользователем. Это дает возможность упростить процесс сохранения персональных данных (например, адреса для доставки счетов или товара и т. д.). При повторном обращении на веб-узел предоставленные ранее сведения могут быть восстановлены, что облегчает повторное использование ранее выбранных возможностей данного узла. Ниже приведены примеры использования файлов cookie.

  • Если пользователь Интернет-магазина ранее указывал адрес для доставки счетов или товара, вместо повторного ввода этих данных можно указать пароль, позволяющий автоматически заполнить соответствующие поля в форме заказа.
  • Файл cookie может содержать сведения о выбранных ранее интересующих темах, которые будут отображаться при каждом посещении веб-узла данным пользователем. Например, на странице с новостями можно указать только интересующие пользователя темы новостей 2http://support.microsoft.com/kb/260971/ru

Чтение и запись Cookie

Следующий пример кода (обработчика события Page_Load ) демонстрирует установку и чтение значения cookie с именем "lastVisit", содержащее значение текущего времени. Если у пользователя cookie уже установлен, код отобразит время последнего посещения страницы пользователем в элементе управления Labe1l. Если при посещении пользователем страницы из предыдущего примера cookie еще не установлен, код покажет сообщение "No value defined"

if (Request.Cookies["lastVisit"] != null)
{
  Server.HtmlEncode(Request.Cookies["lastVisit"].Value);
}
else
{
  Labell.Text = "No value defined";
}
// Установить cookie для следующего визита
Response.Cookies["lastVisit"].Value = DateTime.Now.ToString();
Response.Cookies["lastVisit"].Expires = DateTime.Now.AddDays(1);

Строки запроса

Строки запроса обычно используется для хранения переменных, идентифицирующих страницы, критериев поиска и номеров страниц. Строка запроса это строка, добавленная к URL.

Строки запроса — простой, но ограниченный механизм хранения информации о состоянии между запросами страниц. Например, в строке запроса легко передать количество товара со страницы описания на страницу оформления заказа. Некоторые браузеры и устройства ограничивают длину URL 2083 символами. Другое ограничение состоит в необходимости отправки страницы командой HTTP GET, чтобы значения из строки запроса были доступны для обработки. Следовательно, запросы нельзя добавлять в целевые URL кнопок на формах.

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

Для чтения значения строки запроса необходимо обратиться к набору Request.QueryStrings, как к cookie.

следующий код показывает значения параметров user, prefs и page из строки запроса в элементе управления Label1:

Labell.Text = "User: " +
   Server.HtmlEncode(Request.QueryString["user"]) + ", Prefs: " + 
   Server.HtmlEncode(Request.QueryString["prefs"]) + ", Page: " + 
   Server.HtmlEncode(Request.QueryString["page"]);

Необходимо всегда кодировать cookie и значения в строке запроса с помощью Server. Html Encode перед отображением значения на HTML-страницах. Server. HtmlEncode заменяет HTML-код специальными символами, которые веб-браузер в состоянии только отображать, но не обрабатывать.

Управление состоянием на стороне сервера:

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

Хранение информации на сервере имеет следующие преимущества:

  1. Безопасность. Информация управления состоянием на клиенте может быть похищена с клиентского компьютера или перехвачена в пути, а также она уязвима к модификации злоумышленниками. Следовательно, ни в коем случае не используйте управление состоянием на клиенте для хранения конфиденциальной информации, такой как пароль, уровень доступа или состояние авторизации;
  2. Снижение нагрузки на сеть. При транспортировке больших объемов данных состояния между клиентом и сервером создается значительная нагрузка на канал связи и увеличивается время загрузки страницы, что чревато ростом расходов и снижением масштабируемости. Пересылка больших объемов данных негативно сказывается на эффективности мобильных клиентов, обычно подключенных через медленные каналы связи. Следовательно, громоздкую информацию управления состоянием (более 1 Кб) лучше хранить на сервере.

Параметры управления состоянием на стороне сервера, поддерживаемые ASP.NET:

  • Состояние приложения
  • Состояние сеанса
  • Свойства профиля
  • Поддержка базы данных

Состояние приложения

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

Состояние приложения хранится в объекте-словаре Application (экземпляре класса HttpApplicationState ), который представляет собой набор пар "ключзначение". К нему можно добавлять специфичную для приложения информацию, где она сохранится между запросами страниц. После введения такой информации в состояние приложения сервер обработает ее без участия клиента, причем она становится недоступной клиенту. Состояние приложения — один из лучших механизмов хранения информации, не специфичной для пользователей. Он позволяет всем страницам обращаться к одной копии данных, хранящихся в одной области памяти, а не к множеству отдельных копий.

Теоретически, любой может обратиться к объекту Application, поэтому хранящаяся в нем информация о пользователе уязвима с точки зрения безопасности.

Сохраненные в объекте Application данные теряются при перезапуске приложения. IIS обычно периодически перезапускает приложения ASP.NET, чтобы повысить надежность. При перезагрузке компьютера веб-приложения также перезапускается. Чтобы сохранить информацию в этих случаях, следует читать и записывать значения при обработке событий приложения

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

Использование состояния приложения:

Application["Message"] = "Some string";
Application["AppStartTime"] = DateTime.Now;
string s = (string)Application["Message"];
DateTime startTime = (DateTime)Application["AppStartTime"];

Поскольку значения контейнера Application доступны из всех страниц, то в случае одновременного обращения нескольких потоков к одному значению возникает проблема синхронизации. В качестве решения используются два метода: Lock() и Unlock(). Вызов метода Lock заставляет ASP.NET блокировать все попытки доступа любых других потоков к любой информации из Application. Блокировка снимается вызовом метода Unlock.

Application.Lock();
Application["number"] = (int)Application["number"] + 1;
Application.UnLock();

Одним из недостатков Application является неограниченное время жизни его объектов. Т.е. значения, записанные в эту коллекцию, будут в ней существовать до тех пор, пока они не будут явно удалены (методы Remove, RemoveAll, RemoveAt, присвоение null ).

// удаление SomeGlobalCounter из Application методом Remove
Application.Remove("SomeGlobalCounter");
// удаление SomeGlobalCounter из Application присвоением null
Application["SomeGlobalCounter"] = null;

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

Состояние сеанса

  1. ASP.NET предоставляет состояние сеанса, доступное как класс HttpSessionState, в качестве метода хранения специфичной для сеанса информации, видимой только в пределах сеанса. Состояние сеанса ASP.NET определяет запросы, полученные от обозревателя в течение ограниченного периода времени (сеанса), и предоставляет возможность сохранения значений переменных в течение этого сеанса.

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

Контейнер Session похож на Application, с той лишь разницей, что для каждого пользователя приложения создается своя собственная сессия со своими собственными значениями. Для идентификации пользователей ASP.NET использует 120-битный ключ, именуемый SessionID и состоящий только из ASCII-символов, которые допустимы для использования в URL. В зависимости от настроек веб-приложения, этот ключ сохраняется либо в Cookie либо включается как часть URL.

Пример:

Session["Message"] = "My string";
Session["SessionStartTime"] = DateTime.Now;
string s = (string)Session["Message"];
DateTime startTime = (DateTime)Session["SessionStartTime"];

Коллекция StaticObjects является read-only коллекцией, ее элементы определяются в файле Global.asax с помощью тега <object runat="server" scope="session">.

<object runat="server" scope="session" 
            id="SessionStr" class="System.Text.StringBuilder"/>

Отключение состояния сеанса

Если состояние сеанса не используется, можно повысить производительность, отключив его для всего приложения путем присваивания свойству sessionState mode в файле Web.config значения Off:

<configuration>
  <system.web> 
    <sessionState mode="off"/>
  </system.web> 
</configuration>

Для отключения состояния сеанса на отдельной странице приложения установите страничную директиву EnableSessionState в False.

Свойства профиля

Для использования профилей сначала нужно включить профили, изменив файл конфигурации веб-приложения ASP.NET. В составе конфигурации указывается поставщик профилей — это базовый класс, отвечающий за низкоуровневые задачи хранения и извлечения данных профилей. Можно использовать поставщик профилей, входящий в состав платформы .NET Framework, который хранит данные профилей в SQL Server, или создать и использовать свой собственный поставщик профилей.

Функция профилей настраивается путем определения списка свойств, значения которых необходимо поддерживать. Например, может понадобиться хранить почтовый индекс пользователя, чтобы приложение могло предоставлять ему региональные сведения — например, прогноз погоды. В файле конфигурации для этого потребуется определить свойство профиля с именем PostalCode. Раздел profile файла конфигурации может выглядеть следующим образом:

<profile>
  <properties>
    <add name="PostalCode" />
  </properties>
</profile>

При запуске приложения платформа ASP.NET создает класс ProfileCommon, который создается динамически путем наследования от класса ProfileBase. В динамическом классе ProfileCommon представлены свойства, созданные по определениям свойств профиля, указанным в конфигурации приложения. Экземпляр этого динамического класса ProfileCommon затем задается в качестве значения свойства Profile текущего контекста HttpContext и будет доступен на страницах приложения.

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

Profile.PostalCode = txtPostalCode.Text;

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

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

weatherInfo = GetWeatherInfo( Profile.PostalCode );

Нет необходимости определять, кем является пользователь, или выполнять поиск в базе данных. Простое считывание значения свойства из профиля приводит к тому, что платформа ASP.NET выполняет необходимые действия для идентификации текущего пользователя и поиска значения в постоянном хранилище профилей 3http://msdn.microsoft.com/ru-ru/library/2y3fs9xs.aspx

Дополнительные материалы

  1. http://www.gotdotnet.ru/blogs/abasyuk/6536/
  2. http://msdn.microsoft.com/ru-ru/library/z1hkazw7.aspx
Екатерина Соколова
Екатерина Соколова
Россия, Ухта
Никита Гекторов
Никита Гекторов
Украина, Донецк