Если у вас есть раскрывающиеся списки с большим количеством элементов, и если содержимое этих раскрывающихся списков может быть легко получено при обратной передаче страницы, то это содержимое НЕ ДОЛЖНО помещаться в viewstate. Вместо этого выпадающий список должен быть повторно заполнен на сервере при каждой обратной передаче. Классическим примером этого является раскрывающийся список, содержащий список из 50 штатов. Нет смысла помещать этот контент в viewstate. Эти данные можно кэшировать на сервере и использовать для повторного заполнения раскрывающегося списка при каждой обратной передаче, вместо того, чтобы передавать эти данные взад и вперед клиенту при каждой обратной передаче.
Так как же связать контент с выпадающим списком, не добавляя его в viewstate и не отключая viewstate для элемента управления? Ответ заключается в понимании конвейера событий ASP.Net. Отслеживание состояния существа при вызове метода TrackViewState () после события страницы OnInit. Любые изменения, которые программно вносятся в элемент управления после выполнения TrackViewState (), помещаются в viewstate. Таким образом, если вы привязываете свой раскрывающийся список в событии Page_Load, все содержимое раскрывающегося списка будет помещено в viewstate, что вам часто не нужно.
Таким образом, если вы не хотите, чтобы содержимое вашего выпадающего списка было сериализовано в viewstate, вы должны привязать данные перед тем, как будет выполнен метод TrackViewState (). Лучшее место для этого - событие Init для выпадающего списка. Короче говоря, заполните свой выпадающий список в его Init, и содержимое выпадающего списка НЕ будет сериализовано в viewstate. Конечно, поскольку контент не находится в viewstate, вам нужно будет повторно заполнять его при каждой обратной передаче. Тем не менее, если содержимое кэшируется и его получение дешево (как в случае, например, со списком из 50 штатов), это не является проблемой.
Пример. Допустим, у вас есть раскрывающийся список с именем dropDownList1, и вы можете получить список, содержащий содержимое списка, с помощью метода GetData (). Вы можете заполнить этот список в событии page_load:
protected void Page_Load(object sender, EventArgs e)
{
//Content of dropdown list will be serialized into viewstate
dropDownList1.DataSource = GetData();
Page.DataBind();
}
но если вы сделаете это, контент будет сериализован в viewstate. Если вы заполняете список в событии Init:
protected void dropDownList1_Init(object sender, EventArgs e)
{
//Content of dropdown list will NOT be serialized into viewstate
GetData().ForEach(item => this.dropDownList1.Items.Add(item));
}
содержимое НЕ будет сериализовано в viewstate. До тех пор, пока получить этот контент дешево, вы должны делать это следующим образом.
Подробнее об этом см. в этой превосходной статье о цикле бесконечности. Это лучшая статья, которую я когда-либо видел на viewstate, и, поняв содержание этой статьи, мы смогли более разумно использовать viewstate на наших веб-страницах и значительно сократить размер нашего viewstate.