Прощай, ViewState!
.NET*
Проблема
С самого начала изучения технологии ASP.NET меня неприятно удивили две вещи: наличие (точнее его огромный размер на сложных страницах) состояния представления (ViewState) в виде скрытого поля на странице и именование (ID) контейнеров серверных элементов. После PHP, где под контролем находится каждый выводимый в браузер символ, это было разочарованием.
Ну, с проблемой именования я более-менее смирился, в конце-концов стили для элементов можно применять с помощью class (тем более, что это работает быстрее, чем по id), а для использования id в клиентских скриптах можно вывести свойство ClientID серверного контрола.
ViewState же нужно было обуздать :) Ведь занимающее от 50% размера страницы состояние представления — это не очень хорошо с точки зрения клиентской оптимизации. Плюс к увеличению размера страницы, с позиции SEO тоже на таких страницах не все радужно. Могу сделать предположение, даже не будучи специалистом по поисковикам, что страница с <h1>нужный текст</h1> ранжируется лучше, чем <80кб какой-то фигни><h1>нужный текст</h1> (поправьте меня, если не прав).
Что можно сделать?
Дино Эспозито в своей книге «ASP.NET 2.0. Базовый курс» (гл. 13) предлагает два варианта решения проблемы: отключение ViewState у элементов, для которых его отсутствие не нарушит работу приложения и перенос состояния представления на сервер.
С отключением ViewState все прозрачно, а вот второй способ рассмотрю подробно.
Итак, нам предлагается создать класс, производный от Page, переопределить в нем два метода (сохранения SavePageStateToPersistenceMedium и загрузки LoadPageStateFromPersistenceMedium состояния представления) и реализовать способ сохранения/считывания ViewState вручную. Затем все свои страницы нужно наследовать от этого класса.
Скажите, кто этим занимался когда-нибудь? ;)
Наверняка должен быть более простой путь, когда ничего не нужно реализовывать самому и не затрагивать уже написанный код приложения. И, обратившись к своим более опытным коллегам, нашел этот путь.
Начиная с версии 2.0 в ASP.NET появился механизм адаптеров. С помощью этого механизма можно изменять поведение элементов управления (и страниц тоже), не затрагивая их код.
Создаем адаптер для страницы:
namespace Samples.AspNet.CS {
using System.Web.UI;
public class MyPageAdapter : System.Web.UI.Adapters.PageAdapter {
public override PageStatePersister GetStatePersister() {
return new SessionPageStatePersister(Page);
}
}
}
* This source code was highlighted with Source Code Highlighter.В этом адаптере переопределен метод GetStatePersister, который возвращает объект, используемый веб-страницей для настройки элементов управления и состояний представления. По умолчанию используется HiddenFieldPageStatePersister (хранение ViewState в скрытом поле в браузере), меняем его на SessionPageStatePersister (хранение ViewState в сессии на сервере).
Теперь нужно наш адаптер поключить к страницам.
В папке App_Browsers создаем файл default.browser:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.Page" adapterType="Samples.AspNet.CS.MyPageAdapter" />
</controlAdapters>
</browser>
</browsers>
* This source code was highlighted with Source Code Highlighter.С помощью этого файла осуществляется подключение нашего адаптера ко всем страницам, унаследованным от класса Page.
Пробуем!
P.S. Желательно все же отключать ViewState в любом случае на элементах, где он не нужен.

комментарии (76)