Технология ASP.Net : Управление состоянием
Cookie – файлы
Cookie — это текстовая строка, включаемая в запросы и ответы HTTP (Hypertext Transfer Protocol). Файлы cookie используются для сохранения данных о пользователе, посещающем различные страницы веб-узла или возвращающемся на веб-узел спустя некоторое время. В этой статье представлены сведения о файлах cookie.
Одно из главных назначений файлов cookie — предоставлять удобное средство экономии времени. Файлы cookie позволяют сообщить веб-узлу, что пользователь вернулся на конкретную страницу. Например, при обращении к личной веб-странице или при вводе регистрационных данных файлы cookie помогают серверу восстановить сведения, связанные с текущим пользователем. Это дает возможность упростить процесс сохранения персональных данных (например, адреса для доставки счетов или товара и т. д.). При повторном обращении на веб-узел предоставленные ранее сведения могут быть восстановлены, что облегчает повторное использование ранее выбранных возможностей данного узла. Ниже приведены примеры использования файлов cookie.
- Если пользователь Интернет-магазина ранее указывал адрес для доставки счетов или товара, вместо повторного ввода этих данных можно указать пароль, позволяющий автоматически заполнить соответствующие поля в форме заказа.
- Файл cookie может содержать сведения о выбранных ранее интересующих темах, которые будут отображаться при каждом посещении веб-узла данным пользователем. Например, на странице с новостями можно указать только интересующие пользователя темы новостей 2http://support.microsoft.com/kb/260971/ru
Следующий пример кода (обработчика события 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 Кб) лучше хранить на сервере.
Параметры управления состоянием на стороне сервера, поддерживаемые 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;
В ином случае они будут существовать до завершения работы приложения либо перезагрузки веб-сервера.
Состояние сеанса
- 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