ASP.NET: сжатие ViewState

Каковы последние и самые большие способы сжать содержание ASP.NET ViewState?

Что относительно производительности этого? Действительно ли это стоит того, чтобы сохранить страницы быстрыми и минимизировать трафик данных?

Как может я делать:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3NDEyOWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgkFLGN0b
DAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQxBSxjdGwwMCRDb250ZW50UGxhY2VIb
2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MQUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX01haW5Db250ZW50J
FJhZEJ1dDIFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQyBSxjdGwwMCRDb
250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MwUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX
01haW5Db250ZW50JFJhZEJ1dDQFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCd
XQ0BSxjdGwwMCRDb250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0NQUsY3RsMDAkQ29udGVud
FBsYWNlSG9sZGVyX01haW5Db250ZW50JFJhZEJ1dDXz21BS0eJ7991pzjjj4VXbs2fGBw==" />

Во что-то как это:

<input type="hidden" name="__VIEWSTATE"  id="__VIEWSTATE" 
value="/wEPDwUKMTM4Mjc3N==" />
10
задан Seb Nilsson 4 March 2010 в 14:44
поделиться

6 ответов

Опять же, после некоторого исследования этого я резюмировал свои выводы в блоге о сжатии состояния просмотра .

Вот что я сделал, чтобы сохранить сжатое состояние просмотра:

protected override void SavePageStateToPersistenceMedium(object state) {
    SaveCompressedPageState(state);
}

private void SaveCompressedPageState(object state) {
    byte[] viewStateBytes;
    using(MemoryStream stream = new MemoryStream()) {
        ObjectStateFormatter formatter = new ObjectStateFormatter();
        formatter.Serialize(stream, state);
        viewStateBytes = stream.ToArray();
    }

    byte[] compressed = CompressionHelper.Compress(viewStateBytes);
    string compressedBase64 = Convert.ToBase64String(compressed);

    ClientScript.RegisterHiddenField(ViewStateFieldName, compressedBase64);
}

И для части загрузки этот код заставил меня работать:

protected override object LoadPageStateFromPersistenceMedium() {
    return LoadCompressedPageState();
}

private object LoadCompressedPageState() {
    string viewState = Request.Form[ViewStateFieldName];
    if(string.IsNullOrEmpty(viewState)) {
        return string.Empty;
    }

    byte[] decompressed = CompressionHelper.Decompress(viewState);
    string decompressedBase64 = Convert.ToBase64String(decompressed);

    ObjectStateFormatter formatter = new ObjectStateFormatter();
    return formatter.Deserialize(decompressedBase64);
}
2
ответ дан 3 December 2019 в 15:51
поделиться

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

8
ответ дан 3 December 2019 в 15:51
поделиться
  1. Избегайте использования ViewState
  2. Используйте сжатие на сервере IIS.
  3. Вы можете подключить что-то, что будет сжимать состояние просмотра на странице и из нее, выполнив что-то вроде:
public abstract class PageBase : System.Web.UI.Page
{
    private ObjectStateFormatter _formatter = new ObjectStateFormatter();

    private static byte[] Compress( byte[] data )
    {
            var compressedData = new MemoryStream();
            var compressStream = new GZipStream(output, CompressionMode.Compress, true);
            compressStream.Write(data, 0, data.Length);
            compressStream.Close();
            return compressedData.ToArray();
    }
    private static byte[] Uncompress( byte[] data )
    {
            var compressedData = new MemoryStream();
            input.Write(compressedData, 0, compressedData.Length);
            input.Position = 0;
            var compressStream = new GZipStream(compressedData, CompressionMode.Decompress, true);
            var uncompressedData = new MemoryStream();
            var buffer = new byte[64];
            var read = compressStream.Read(buffer, 0, buffer.Length);

            while (read > 0)
            {
                uncompressedData.Write(buffer, 0, read);
                read = compressStream.Read(buffer, 0, buffer.Length);
            }
            compressStream.Close();
            return uncompressedData.ToArray();
    }
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
        var ms = new MemoryStream();
        _formatter.Serialize(ms, viewState);
        var viewStateBytes = ms.ToArray();
        ClientScript.RegisterHiddenField("__COMPRESSED_VIEWSTATE"
            , Convert.ToBase64String( Compress(viewStateArray)) );
    }
    protected override object LoadPageStateFromPersistenceMedium()
    {
        var compressedViewState = Request.Form["__COMPRESSED_VIEWSTATE"];
        var bytes = Uncompress( Convert.FromBase64String( compressedViewState ) );
        return _formatter.Deserialize( Convert.ToBase64String( bytes ) );
    }
}
8
ответ дан 3 December 2019 в 15:51
поделиться

Лучший способ минимизировать состояние просмотра - просто не использовать его. Это заставит вас выполнить дополнительную работу по программированию (повторное заполнение контрольных значений и т. Д. При обратной публикации, но это сэкономит вам количество информации, которую вы отправляете в браузер). Вы не можете вмешиваться в это.

Вот ссылка на состояние просмотра в MSDN:

http://msdn.microsoft.com/en-us/library/ms972976.aspx

Вот ссылка, описывающая некоторые передовые практики:

http://mnairooz.blogspot.com/2007/01/aspnet-20-viewstate-and-good-practices.html

И еще один об отключении ViewState:

http://www.codeproject.com /KB/aspnet/ASPNET_Best_Practices.aspx

0
ответ дан 3 December 2019 в 15:51
поделиться

Себ, ViewState уже сжат... вот что вы видите... сжатую версию ваших элементов управления. Если вы хотите меньше накладных расходов, то не используйте viewstate :)

Использование ViewState должно быть сведено к минимуму!

1
ответ дан 3 December 2019 в 15:51
поделиться

Это визуализация вашего опубликованного состояния просмотра в формате XML:

<viewstate>
  <Pair>
    <Pair>
      <String>1382774129</String>
    </Pair>
  </Pair>
</viewstate>
<controlstate>
  <HybridDictionary>
    <DictionaryEntry>
      <String>__ControlsRequirePostBackKey__</String>
      <ArrayList>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut3</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
        <String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
      </ArrayList>
    </DictionaryEntry>
  </HybridDictionary>
</controlstate>

По сути, это всего лишь несколько радиокнопок, которые хотят знать об их существовании. (браузеры не отправляют поле с постданными, если оно не отмечено). Это уже довольно минимально.

Скорее всего, его можно сжать, подключив методы загрузки / сохранения или модули HTTP, но это может быть непрактично и не совсем необходимо.


В случае, если состояние просмотра намного больше в вашем реальном приложении, вообще избегайте получения объектов в состоянии просмотра. Это может быть достигнуто путем инициализации элементов управления в методах OnInit () или Page_Init () вместо стандартных Page_Load () .

Обоснование этого можно найти на странице http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx { {1}} и http://msdn.microsoft.com/en-us/library/ms972976.aspx

Краткое резюме:

  • ViewState - это просто резервное хранилище для почти всех свойств элемента управления, включая по умолчанию.
  • После установки значений по умолчанию с помощью OnInit () будет вызван метод TrackViewState () .
  • Любые последующие изменения (например, посредством Page_Load () ) или обработчика событий будут отслеживаться и отправляться клиенту. Таким образом, эти элементы управления могут восстановить свое состояние при следующем запросе.
  • Вместо того, чтобы полагаться на структуру для восстановления объектов, при необходимости восстанавливайте объекты в OnInit () . (например, повторное заполнение параметров DropDownList из базы данных).

Одно исключение:

Если элемент управления динамически добавляется в дерево элементов управления, он воспроизводит догоняющий. Их метод OnInit () может быть запущен позже, в результате чего эти свойства в конечном итоге окажутся в состоянии просмотра. Если инициализация элемента управления не может произойти в OnInit () , установка EnableViewState = "false" может использоваться в качестве временного решения.

Каждый раз, когда мое состояние просмотра неожиданно увеличивается, я использую приложение «ViewState Decoder 2.2», чтобы узнать, что попало в состояние просмотра. Часто данные не нужны.

И последнее слово:

Состояние просмотра не используется для повторного заполнения форм !! Эти значения уже отправлены вместе с постданными.

1
ответ дан 3 December 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: