Как стать автором
Обновить

asp.net: использование механизма ControlState

Время на прочтение3 мин
Количество просмотров2.9K
Эта заметка предназначена для тех, кто не знает, что такое ControlState и как им пользоваться. Если вы знакомы с этой техникой сохранения состояния страницы, то можете смело пропустить этот топик.

Всем программистам asp.net известна технология ViewState, которая предлагает способ по умолчанию для сохранения состояния web-страниц и элементов управления. Не буду здесь говорить о плюсах и минусах, и без этого известно, что ViewState – это палка о двух концах, на одной стороне которой удобство, а на другой гигантский объем сгенерированных страниц (к примеру, в случае, если вы включите ViewState для GridView). Так уж вышло, что один из основных механизмов asp.net при разработке частенько выключается в угоду производительности.

Обычно, ViewState отключают для всей страницы просто указав
<% Page EnableViewState=«false»%>
Выгода в данном случае существенна, страницы буду содержать только разметку (ну плюс, обвязку asp.net) и к тому же, ни один элемент управления гарантированно не сможет генерировать ViewState-данные.
Тут есть одно но, выключая ViewState, вы его выключаете полностью и, к примеру, следующий код, работающий с ViewState и описанный в этой статье про сниппеты habrahabr.ru/blog/net/41790.html просто не будет работать как надо.
  public int MyProperty
  {
    get
    {
      object o = ViewState[«MyProperty»];
      return (o != null)? (int)o: 0;
    }
    set
    {
      ViewState[«MyProperty»] = value;
    }
  }
* This source code was highlighted with Source Code Highlighter.


Между тем, существует способ использовать ViewState и при EnableViewState=«false». Эта техника называется ControlState. И если ViewState выключить можно, то ControlState — нет. Рассмотрим пример:
  [Serializable]
  struct PageStateStruc
  {
    public FormState CurrentState;
    public int? CurrentResume;
    public int CurrentSection;
  }
  PageStateStruc PageState;

  protected override void OnInit(EventArgs e)
  {
    Page.RegisterRequiresControlState(this);
    base.OnInit(e);
  }

  protected override object SaveControlState()
  {
    return PageState;
  }

  protected override void LoadControlState(object savedState)
  {
    PageState = (PageStateStruc)savedState;
  }
* This source code was highlighted with Source Code Highlighter.


Здесь определяется некая структура данных PageStateStruc, экземпляр которой мы будем сохранять. Обратите внимание на атрибут Serializable, который для используемой структуры обязателен. Тут же определяется экземпляр структуры PageState.

Далее, в обработчике OnInit вызывается метод RegisterRequiresControlState, который регистрирует текущую страницу как элемент управления, ControlState которого следует сохранять. Вместо this можно указать любой пользовательский элемент управления. Рекомендуется осуществлять вызов RegisterRequiresControlState именно в OnInit.

Завершают картину два перегруженных метода SaveControlState и LoadControlState, которые, как это видно, просто осуществляют загрузку и выгрузку необходимых данных. Вызов этих методов asp.net берет на себя.
Это все! Данные PageState между запросами к странице будут автоматически сохраняться. По сути, для сохранения данных между вызовами страницы нам необходимо только определить вид данных и описать, как эти данные необходимо сохранять/загружать. Остальное делает asp.net.

Послесловие


Я рекомендую отключать ViewState в масштабе всей страницы. В случаях, когда нужно сохранять какие-нибудь данные, используйте ControlState. Однако, если эти данные представляют собой всего лишь значение одной переменной или свойства, то разумнее будет использовать элемент управления HiddenField. Несколько опытов показали, что разметка, которую сгенерирует HiddenField для одного поля, займет меньше места, чем строка ViewState, которую для этого же поля сгенерирует механизм ControlState.
Теги:
Хабы:
Всего голосов 13: ↑8 и ↓5+3
Комментарии9

Публикации

Работа

.NET разработчик
43 вакансии

Ближайшие события