Pull to refresh

Перемещаем ViewState в конец страницы

.NET *

Проблема


Продолжаем борьбу с ViewState при использовании WebForms (использование данной технологии обусловлено политикой партии применением паттерна WCSF в проектах фирмы).

В предыдущей статье я рассмотрел возможность переноса ViewState из браузера пользователя в сессию. Здорово, что удалось избавиться от ViewState на странице, но с этим способом иногда может возникнуть проблема перезапуска стейт-сервера (хотя мои более опытные товарищи с ней не сталкивались).

Если всё-таки вы решили оставить ViewState на стороне браузера, возникает другая проблема (помимо раздувшегося html) — при прочих равных условиях поисковики ранжируют информацию лучше, если она содержится ближе к началу страницы. Естественно наличие громадного ViewState в начале каждой страницы нежелательно.


Решение


Итак, все что нам нужно, это перехватить выходной поток, вырезать из начала страницы скрытое поле с ViewState и вставить его перед закрывающим тегом form.
Напишем адаптер страницы:
using System.IO;
using System.Web.UI;

namespace MyCompany.Web
{
  /// <summary>
  /// Адаптер для перемещения ViewState в конец страницы
  /// </summary>
  public class MoveViewStatePageAdapter : System.Web.UI.Adapters.PageAdapter
  {
    protected override void Render(HtmlTextWriter writer)
    {
      // получаем HTML, генерируемый предком
      var sw = new StringWriter();
      var hw = new HtmlTextWriter(sw);

      base.Render(hw);
      var html = sw.ToString();

      hw.Close();
      sw.Close();

      // ищем вхождение ViewState
      var start = html.IndexOf(@"<input type=""hidden"" name=""__VIEWSTATE""");

      if (start > -1)
      {
        var end = html.IndexOf("/>", start) + 2;

        // удаляем ViewState
        var viewstate = html.Substring(start, end - start);
        html = html.Remove(start, end - start);

        // ищем закрывающий тег формы и пишем перед ним ViewState
        var formend = html.IndexOf("</form>") - 1;
        html = html.Insert(formend, viewstate);
      }

      // выводим HTML
      writer.Write(html);
    }
  }
}

* This source code was highlighted with Source Code Highlighter.


В папке App_Browsers создаем файл default.browser с содержимым:
<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.Page" adapterType="MyCompany.Web.MoveViewStatePageAdapter" />
    </controlAdapters>
  </browser>
</browsers>


* This source code was highlighted with Source Code Highlighter.


Смотрим результат!

P.S. Использован код из Moving ViewState to the Bottom of the Page
Еще одно решение с использованием http-модуля.
Tags:
Hubs:
Total votes 12: ↑9 and ↓3 +6
Views 702
Comments 10
Comments Comments 10

Posts