4.2. Управление состоянием на сервере
ASP.NET поддерживает два способа обмена информацией между веб-страницами без отправки данных клиенту: первый использует состояние приложения, второй — состояние сеанса. Состояние приложения (Application State) доступно для всех страниц независимо от запрашивающего, а состояние сеанса (Session state)— для всех открытых пользователем страниц, но только во время их просмотра. В обоих случаях при перезапуске приложения данные состояния теряются. Чтобы сохранить при этом данные, следует хранить их с помощью свойств профиля.
Состояние приложения
ASP.NET сохраняет значения в состоянии приложения — глобальной области памяти, доступной для всех страниц веб-приложения. Следовательно, состояние приложения можно применять для сохранения информации между запросами страниц и циклов обмена данными между клиентом и сервером
Состояние приложения хранится в объекте-словаре Application (экземпляре класса HttpApplicationState), который представляет собой набор пар «ключ—значение». К нему можно добавлять специфичную для приложения информацию, где она сохранится между запросами страниц. После введения такой информации в состояние приложения сервер обработает ее без участия клиента, причем она становится недоступной клиенту. Состояние приложения — один из лучших механизмов хранения информации, не специфичной для пользователей. Он позволяет всем страницам обращаться к одной копии данных, хранящихся в одной области памяти, а не к множеству отдельных копий.
Но нужно помнить, что нельзя хранить информацию, специфичную для пользователя, в состоянии приложения. Для ее хранения используется состояние сеанса, описанное ниже. Теоретически, любой может обратиться к объекту Application, поэтому хранящаяся в нем информация о пользователе уязвима с точки зрения безопасности.
Сохраненные в объекте Application данные теряются при перезапуске приложения. IIS обычно периодически перезапускает приложения ASP.NET, чтобы повысить надежность При перезагрузке компьютера веб-приложения также перезапускается. Чтобы сохранить информацию в этих случаях, следует читать и записывать значения при обработке событий приложения, как описано в следующем разделе.
Обработка событий приложения
ASP.NET поддерживает три события, позволяющие инициализировать переменные Application (либо освободить ресурсы по завершении работы приложения) и обработать ошибки Application:
Application_Start
Генерируется при запуске приложения. Лучший момент инициализации переменных Application.
Application_End
Генерируется при остановке приложения. Используется для освобождения занятых приложением ресурсов и ведения журналов.
Application_Error
Генерируется при возникновении необработанной ошибки. Применяется для регистрации ошибок.
Для реализации обработки этих событий добавьте файл Global.asax в ваш проект следующим образом:
В Visual Studio щелкните Website | Add New Item.
Щелкните Global Application Class и выберите Add.
Visual Studio по умолчанию добавит файл Global.asax с объявлениями обработчиков Application_Start, Application_End и Application_Error, а также Session_Start и Session_End. Следующий код демонстрирует реализацию Global.asax для мониторинга пользователей средствами объекта Application[“UsersOnline”]:
//C#
void Application_Start(object sender, EventArgs e)
{
// Код, исполняемый при запуске приложения
Application["UsersOnline"] = 0;
}
void Session_Start(object sender, EventArgs e)
{
// Код, исполняемый при запуске сеанса
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;
Application.UnLock();
}
void Session_End(object sender, EventArgs e)
{
// Код, исполняемый при завершении сеанса.
// Note: Событие Session_End генерируется, только если активен режим sessionstate
// is set to InProc in the Web.config file. Если же активен режим StateServer
// либо SQLServer, это событие не генерируется.
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] - 1;
Application.UnLock();
}
Чтение и запись состояния приложения
Для чтения и записи данные состояния приложения применяют объект Application (экземпляр класса HttpApplicationState), делается это, как в случае объекта ViewState (или любого набора вообще). Поскольку одновременно может работать множество веб-страниц, на время вычислений и обновления объекта Application, последний необходимо заблокировать, аналогично тому, как блокируют общие ресурсы в многопоточных приложениях. Например, следующий код блокирует объект Application для приращения значения переменной:
//C#
Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"])+1;
Application.UnLock();
Если не блокировать объект Application, возможна потеря изменений, внесенных другими страницами между чтением текущего значения и записью нового. При инициализации переменных в Application_Start блокировать объект Application не требуется.
Для чтения значений из Application достаточно привести их к соответствующему типу. Как прочитать из Application значение типа Integer, показано в следующем примере:
//C#
(int)Application["PageRequestCount"]
