asp.net: Використання механізму ControlState

Ця нотатка призначена для тих, хто не знає, що таке 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.

Тут визначається якась структура даних PceStceStruc, екземпляр якої ми будемо зберігати. Зверніть увагу на атрибут Serializable, який використовується для структури обов'язковий. Тут же визначається примірник структури PceState.

Далі, в обробнику OnInit викликається метод RegisterRequiresControlState, який реєструє поточну сторінку як елемент управління, ControlState якого слід зберігати. Замість this можна вказати будь-який користувацький елемент керування. Рекомендується здійснювати виклик RegisterRequiresControlState саме в OnInit.

Завершують картину два перевантажених методи SaveControlState і LoadControlState, які, як це видно, просто здійснюють завантаження і вивантаження необхідних даних. Виклик цих методів asp.net бере на себе.

Це все! Дані PceState між запитами до сторінки будуть автоматично зберігатися. По суті, для збереження даних між викликами сторінки нам необхідно тільки визначити вид даних і описати, як ці дані необхідно зберігати/завантажувати. Решта робить asp.net.

Післямова

Я рекомендую відключати ViewState в масштабі всієї сторінки. У випадках, коли потрібно зберігати якісь дані, використовуйте ControlState. Однак, якщо ці дані являють собою всього лише значення однієї змінної або властивості, то розумніше буде використовувати елемент управління HiddenField. Кілька дослідів показали, що розмітка, яку згенерує HiddenField для одного поля, займе менше місця, ніж рядок ViewState, який для цього ж поля згенерує механізм ControlState.