Управление состоянием страниц на клиенте
Файлы к лабораторной работе Вы можете скачать здесь.
Главная особенность удаленных приложений состоит в том, что они могут одновременно обрабатывать множество пользователей. К тому же сервер может выполнять одновременно несколько разных приложений. Поэтому среда исполнения устроена так, что после обработки единичного запроса очередного пользователя память сервера немедленно очищается от кода запрошенной страницы, освобождая ресурсы для новых возможных запросов. Измененное состояние страницы, информация о пользователе и другие оперативные данные приложения теряется безвозвратно, а при следующем запросе страница загружается в память сервера в первозданном виде, как при первом. Такой механизм называется работой без сохранения состояния.
Такой факт вынуждает разработчиков Web-приложений изыскивать способы хранения информации о состоянии между запросами, с последующим ее извлечением и использованием. В ASP.NET существует два способа хранения информации между запросами: на клиенте и на сервере. Разработчик сайта сам решает, какую группу методов хранения данных состояния ему выбрать.
Хранение информации на клиенте имеет следующие преимущества:
- Лучшая масштабируемость - не расходуется память сервера для хранения состояния, что позволяет обслужить больше клиентов
- Поддержка множества Web-серверов - обработку поступающих запросов можно распараллелить между несколькими серверами. При этом код приложения модифицировать не нужно, поскольку вся необходимая информация о текущем состоянии страницы поступает вместе с каждой обратной отсылкой
Хранение информации на сервере имеет следующие преимущества:
- Безопасность - защищенность данных состояния от злоумышленников. Информация управления состоянием на клиенте может быть похищена с клиентского компьютера или перехвачена в пути. А хранение на сервере конфиденциальных данных, таких как пароль, уровень доступа, состояние авторизации делают это безопасным
- Снижение нагрузки на каналы связи - снижение времени загрузки страницы и увеличение масштабируемости, особенно для мобильных клиентов
Управление состоянием страниц на клиенте
Управление состоянием путем хранения данных на клиенте удобно с точки зрения экономии памяти сервера, но требует дополнительных ресурсов канала связи, поскольку данные курсируют между клиентом и сервером при каждом запросе и отклике. К тому же их трудно защитить от злонамеренного пользователя.
Различают следующие методы хранения данных на клиенте:
- Состояние вида (view state) - используется для сохранения значений элементов управления, добавленных конечным пользователем. Применение состояния вида основано на свойстве ViewState типа System.Web.UI.StateBag, наследуемом от класса Control любым элементом управления и самой страницей.
- Скрытые поля (hidden fields) - сохранение данных в скрытых полях HTML-вывода. Они также хранят информацию об одной странице, но в отличие от состояния вида скрытые поля не поддерживают хэширование, шифрование, сжатие и хранение по частям. При использовании скрытых полей данные формы на сервер должны отправляться методом POST (по щелчку кнопки Submit ), а не методом GET (по щелчку на гиперссылке).
- Строки запроса (query strings) - сохранение данных в URL. Видимы для пользователя в поле адреса
- Межстраничные обратные отсылки - присланные вызывающей страницей данные остаются в памяти сервера на момент работы страницы-приемника
- Куки-наборы ( cookie -файлы) - созданные на сервере данные записываются на компьютер клиента в небольших файлах (в количестве до 20 файлов и размером до 4 Кб каждый) и автоматически пересылаются броузером на сервер вместе с каждым запросом. Это лучший способ хранения состояния, доступного многим страницам приложения
Рассмотрим последовательно перечисленные методы хранения состояния на клиенте.
Состояние вида
Это простой способ хранения информации на клиенте между обратными отсылками для одной и той же страницы. Вспомним, как обрабатывается страница на сервере. Для этого рассмотрим свежий отклик сервера, только что полученный броузером. В нем броузеру вместе с отображаемым HTML-кодом в скрытых полях была прислана информация со значениями состояния элементов управления страницы на момент отправки с сервера. Пользователь через броузер меняет состояние некоторых элементов и инициирует обратную отсылку.
При поступлении обратной отсылки на сервер в память загружается адресуемая страница в своем первозданном виде, инициализируются ее интерфейсные элементы начальными настройками, затем извлекается поступившая в скрытых полях информация о состоянии на момент предыдущего отклика и свойства элементов корректируются. После этого срабатывают события элементов управления о последних действиях пользователя и состояние элементов управления еще раз корректируются в обработчиках.
Таким образом, состояние интерфейсных элементов при создании страницы перезаписывается по меньшей мере три раза:
- первоначальными настройками
- последними сохранными значениями
- новыми значениями, инициированными пользователем
Все серверные Web-элементы управления используют состояние вида включенным по умолчанию (не обязательно включать EnableViewState="true" ). В состав каждого из них входит свойство-коллекция ViewState, наследуемое от класса System.Web.UI.Control. Это же свойство напрямую наследует и класс Page, который мы расширяем при проектировании активной страницы. Свойство создается и заполняется поступившими данными вместе с объектом страницы, а значит мы программно можем использовать это страничное свойство для сохранения и извлечения информации между запросами одной и той же страницы.
После обработки страницы ее текущее состояние, а также состояние элементов управления, автоматически хэшируется (hash - мусор; не путайте с кэшем - сохранением в памяти) и строка с хэшем пересылается броузеру в скрытом поле страницы вместе с отображаемым HTML. Если данные получаются очень объемные и не помещаются в одном поле, то ASP.NET автоматически делит их на части и записывает в нескольких скрытых полях. Максимальный объем одного скрытого поля определяется свойством maxPageStateFieldLength класса Page (по умолчанию равен -1 ). Для изменения начальных настроек объекта страницы значение этого свойства нужно поместить в конфигурационный файл, например
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> <compilation debug="true" /> <pages maxPageStateFieldLength="1024" /> </system.web> </configuration>
Коллекция ViewState построена по типу словаря (ассоциативного массива), в котором значения адресуются строковыми уникальными ключами. Элементами коллекции являются ссылки на объекты обобщенного типа Object, поэтому она способна хранить объекты любого типа. При извлечении из коллекции состояния вида данные нужно приводить к соответствующему типу. Если в коде попытаться извлечь значение, которого нет в коллекции, будет выдано исключение NullReferenceException, поэтому необходима предварительная проверка возвращаемой ссылки на null -значение.
Не все типы объектов могут быть сохранены в состоянии вида. Простые типы сохраняются безусловно, а более сложные типы должны поддаваться сериализации (преобразовываться в поток байтов). Если объявлению класса предшествует атрибут [Serializable], то порожденный этим классом объект можно сохранять в состоянии вида. В противном случае, при попытке сохранить такой объект в состоянии вида ASP.NET выдаст ошибку выполнения. Библиотечный тип Hashtable из пространства имен System.Collections также представляет собой словарь с полями Key и Value. Он поддается сериализации, поэтому настроенный объект такого типа можно целиком сохранять и восстанавливать в ViewState.