| Украина, Киев |
Управление состоянием страниц на клиенте
Упражнение 3. Восстановление состояния вида элемента списка через коллекцию запроса
Иногда состояние вида в элементе полезно отключить, чтобы уменьшить нагрузку на каналы связи. Но для некоторых элементов это нарушает их нормальную работу. Возьмем, например, списки ListBox и DropDownList. Когда они заполнены большим количеством элементов, объем пересылаемой информации состояния вида очень большой и это свойство лучше отключить. Для восстановления состояния выделенного элемента списка в этом случае можно воспользоваться информацией из коллекции Request.Form страницы.
-
Добавьте
к проекту страницу с именем ViewStateList.aspx без
файла отделенного кода и назначьте ее стартовой -
Оформите
страницу так, чтобы код разметки был следующим
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<h2>Отключение состояния вида в списках</h2>
<asp:ListBox ID="ListBox1" runat="server" Height="200px" Width="150px" />
<asp:DropDownList ID="DropDownList1"
runat="server" Width="150px">
</asp:DropDownList><br />
<br />
<asp:Button ID="Button1" runat="server" Text="Отправить" /></div>
</form>
</body>
</html>
Листинг
35.7.
Код интерфейсной части страницы ViewStateList.aspx
-
Этому
коду в режиме проектирования соответствует следующее представление
-
Двойным
щелчком на свободном месте страницы в режиме Design создайте
блок скриптов с заготовкой обработчика Page_Load()
-
Поместите
в обработчик Page_Load() код заполнения списков
видимым содержимым, который будет срабатывать при каждом запросе
страницы
<script runat="server">
// Поле класса страницы
private const int maxCount = 100;
protected void Page_Load(object sender, EventArgs e)
{
// Заполняем списки программной генерацией значений
for (int i = 0; i < maxCount; i++)
{
ListBox1.Items.Add("Опция " + (i + 1).ToString());
DropDownList1.Items.Add("Опция " + (i + 1).ToString());
}
}
</script>
Листинг
35.8.
Обобработчик Page_Load() для заполнения списков
-
Выполните
страницу и убедитесь, что при каждом новом запросе по щелчку
на кнопке Submit отмеченные пользователем
опции списков возвращаются сервером сохраненными -
После
нескольких обратных отсылок щелкните правой кнопкой мыши
в клиентской области окна броузера и выполните команду View
Source, чтобы просмотреть HTML-содержимое, присланное
сервером
Мы видим большое количество пересылаемой информации в скрытых полях, а также последовательное увеличение содержимого списков. Это происходит потому, что каждое новое состояние списков направляется клиенту для хранения вместе с очередным откликом сервера. При возвращении на сервер последнее состояние списков восстанавливается и к нему добавляется генерация новых значений, выполненных методом Add() в обработчике Page_Load().
Работает механизм автоматического сохранения состояния вида ASP.NET. Чтобы посмотреть, какой при этом получается объем пересылаемой информации, именно касающийся работы этого механизма, нужно включить работу ASP.NET в режиме выдачи трассировки на индивидуальных страницах. Это можно сделать, если добавить атрибут Trace="true" в директиву @ Page страницы, либо через утилиту WAT, запустив ее командой Website/ASP.NET Configuration (или щелкнуть на пиктограмме в панели Solution Explorer ).
-
Запустите
утилиту WAT, пойдите последовательно
по ссылкам Application
Configuration/Configure
debugging and tracing и включите флажки " Capture
tracing information "
и " Display tracing information on ondividual
pages " -
Закройте
утилиту WAT
В результате этих действий файл конфигурации примет вид
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<trace enabled="true" pageOutput="true" />
<compilation debug="true" />
</system.web>
</configuration>
Листинг
35.9.
Файл web.config после включения трассировки утилитой WAT
-
Вновь
запустите страницу ViewStateList.aspx, поманипулируйте
с интерфейсными элементами, выполните обратную отсылку и
проанализируйте секцию Control Tree в результатах
трассировки, которая будет, примерно, такой
Объем пересылаемой по каналам связи в оба конца информации получается огромным до неприличия. Причем с каждой новой отсылкой он катастрофически нарастает, добавляя к прежним сохраненным значениям сгенерированные в коде новые значения списков. Отключим сохранение состояния вида в списках.
-
Перейдите
в режим Design редактора страницы ViewStateList.aspx,
выделите одновременно оба списка и через панель Properties сбросьте
их свойства EnableViewState в значение False
-
Запустите
страницу ViewStateList.aspx и убедитесь,
что объем сохраняемого состояния вида для списков стал нулевым -
Вновь
включите сброшенные свойства EnableViewState для
списков -
Добавьте
в директиву @Page общие для всех элементов
страницы атрибуты EnableViewState = "false" и EnableEventValidation = "false"
Замечание. Если количество запросов превысит заданное параметром трассировки requestLimit значение (по умолчанию 10), то ASP.NET при исполнении не будет включать результаты трассировки в страницу. В этом случае нужно при очередном запуске тестового броузера вызвать через строку адреса страницу trace.axd и щелкнуть на ссылке " clear current trace " этой страницы. Включить безлимитную трассировку можно более просто - добавить в директиву @ Page страницы параметр Trace=true
<trace enabled="true" pageOutput="true" />
и добавьте в директиву @Page страницы атрибут Trace = "true", чтобы включить индивидуальную трассировку страницы
Мы видим, что при отключении сохранения состояния вида уменьшился и общий объем страницы. Но зато сервер в своих откликах не стал сохранять выбранные клиентом опции списков. Исправим этот недостаток программно, воспользовавшись тем фактом, что с каждым запросом выбранные значения передаются на сервер в словарь Request.Form объекта страницы.
-
Добавьте
к странице в конец обработчика Page_Load() код восстановления
выбора пользователя в списках
<script runat="server">
// Поле класса страницы
private const int maxCount = 100;
protected void Page_Load(object sender, EventArgs e)
{
// Заполняем списки программной генерацией значений
for (int i = 0; i < maxCount; i++)
{
ListBox1.Items.Add("Опция " + (i + 1).ToString());
DropDownList1.Items.Add("Опция " + (i + 1).ToString());
}
// Отслеживание выделенных пользователем опций списков
if (this.IsPostBack)
{
string text = this.Request.Form["ListBox1"];
ListBox1.Items.FindByText(text).Selected = true;
text = this.Request.Form["DropDownList1"];
DropDownList1.Items.FindByText(text).Selected = true;
}
else
ListBox1.SelectedIndex = DropDownList1.SelectedIndex = 0;
}
</script>
Листинг
35.10.
Код восстанавления состояния списков
Броузер с обратной отсылкой присылает на сервер значения выделенных элементов списка, собираемых дескриптором <form> из HTML-кода, представленного примерно таким фрагментом
<select size="4" name="ListBox1" id="ListBox1" style="height:200px;width:150px;"> <option selected="selected" value="Опция 1">Опция1</option> <option value="Опция 2">Опция 2</option> <option value="Опция 3">Опция 3</option> .................................................. </select>
Фактически броузер посылает пару ListBox1=Опция 1, которая попадает в словарь Request.Form, доступный для извлечения и использования в коде страницы на стороне сервера. Мы находим это значение в сгенерированной коллекции значений списка и настраиваем этот элемент коллекции как выделенный. После таких настроек список сгенерирует в текущем отклике сервера нужный HTML-код, соответствующий состоянию списка на клиенте перед обратной отсылкой.
-
Запустите
страницу ViewStateList.aspx с включенной
трассировкой и убедитесь, что выбранные опции списков сохраняют
свои позиции и ASP.NET генерирует небольшой объем клиентского
кода
Таким образом мы выяснили, что состояние вида элементов управления, которое включено по умолчанию, не всегда является полезным либо просто не используется, и тогда его лучше отключать. Отключить состояние вида можно следующим образом:
- На уровне приложения для всех страниц в файле web.config текущего
узла web-дерева сайта
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> <compilation debug="true" /> <pages enableViewState="false" /> </system.web> </configuration> - На уровне страницы, добавив в директиву @ Page параметр EnableViewState="false" (в коде свойство Page.EnableViewState = false или this.EnableViewState = false )
- На уровне элемента управления, добавив в дескриптор элемента атрибут EnableViewState = "false" (в коде свойство Элемент .EnableViewState = false )
Если более общая настройка сохранения состояния вида выключена, а для каких-то страниц или элементов управления ее нужно включить, то в соответствующее место следует добавить атрибут EnableViewState = "true".
