Pull to refresh

Прощай, 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 в любом случае на элементах, где он не нужен.

Используемая информация:

Tags:
Hubs:
Total votes 44: ↑32 and ↓12 +20
Views 6.5K
Comments 76
Comments Comments 76

Posts