Ошибка в реализации Label ASP.ViewState? - PullRequest
1 голос
/ 15 мая 2009

РЕДАКТИРОВАТЬ 2: Ну, я пошел в код. Обратите внимание, что они делают здесь. Они говорят load viewstate, а затем поворачиваются и устанавливают свойство Text в то, что было в viewstate. После вызова LoadViewState отслеживание состояния просмотра включено, и это приводит к поведению, которое я наблюдаю. Я думаю, что код должен сказать:

if (s! = Text) {Text = s;}. Это позволит полностью избавиться от проблемы и сохранить любой инвариант, в котором они нуждаются.

/// <internalonly/>
        /// <devdoc>
        ///    <para>Load previously saved state.
        ///       Overridden to synchronize Text property with LiteralContent.</para> 
        /// </devdoc>
        protected override void LoadViewState(object savedState) { 
            if (savedState != null) { 
                base.LoadViewState(savedState);
                string s = (string)ViewState["Text"]; 
                if (s != null)
                    Text = s;
            }
        } 

Редактировать: Из всех моих тестов это влияет только на элемент управления Label. Я все еще думаю, что это ошибка.

Это веб-сайт ASP.NET 3.5.

Рассмотрим следующую страницу .aspx: (html, голова, тело и т. д. отрезаны)

<form id="form1" runat="server">
        <asp:Label runat="server" ID="label1">
            This is a lot of text. 
            This is a lot of text. 
            This is a lot of text. 
            This is a lot of text. 
            This is a lot of text. 
            This is a lot of text. 
            This is a lot of text.             
        </asp:Label>
        <asp:Button runat="server" ID="button1" Text="Click" OnClick="button1_Click" />
        <script>
            document.write(document.getElementById("__VIEWSTATE").value.length);
        </script>
    </form>

На странице указан следующий код:

protected void button1_Click(object sender, EventArgs e) {
        //label1.AccessKey = "a";
    }

Да, эта строка закомментирована. Подойдя к этому. Итак, когда вы нажмете кнопку, вы увидите, что состояние просмотра составляет 52 байта. Несмотря на то, что на метке много текста, конечно, способ работы viewstate заключается в том, что ему не нужно сохранять много текста в viewstate, поскольку начальное значение свойства Text никогда не менялось. ХОРОШО. Все идет нормально. Это все ожидаемое поведение. Фактически, даже если метка содержала 1 мегабайт текста, размер состояния просмотра все равно составлял бы 52 байта. ХОРОШО. Теперь измените метод на

protected void button1_Click(object sender, EventArgs e) {
        label1.AccessKey = "a";
    }

Неважно, какое свойство мы меняем. Теперь нажмите кнопку. Размер ViewState достигает 92 байтов. Хорошо 40 байтов для хранения односимвольного ключа доступа, немного, если вы спросите меня, но что угодно :) Теперь нажмите кнопку снова. Какой размер представления сейчас? Должно быть 92 байта правильно? Это 480 . Нажав больше, он останется размером 480 байт. Что происходит? Изменение свойства метки привело к тому, что метка начала сохранять метку TEXT в состоянии просмотра. Какие???? Вставьте 100K текста в метку, и вы увидите, что состояние просмотра поднимется до ~ 100K.

Это ошибка? Как это возможно ожидаемое поведение?

Ответы [ 3 ]

3 голосов
/ 15 мая 2009

Он хранит не только один символ, но и свойство, к которому он применяется.

См. http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx для получения дополнительной информации о том, как работает viewstate.

Хотя могут быть способы, в которых viewstate может вести себя не так, как вы ожидаете, вряд ли будут какие-либо ошибки, так как viewstate является центральным в работе ASP.NET.

1 голос
/ 25 января 2010

ASP.NET dev здесь :) И автор статьи ViewState упомянут.

Говоря как я, а не как МС, просто для ясности. Да, это ошибка. Чтобы пролить немного света на то, почему код устанавливает свойство, когда, по-видимому, это не нужно (поскольку значение уже сохранено во ViewState - зачем устанавливать его, которое просто снова поместит его во ViewState?). Если вы посмотрите на установщик для текста, вы увидите, что в дополнение к установке значения в ViewState, он вызывает Controls.Clear (). Это связано с тем, что Label поддерживает наличие дочерних элементов управления в виде «текста», а также литеральной строки. Если он не установил свойство Text в LoadViewState, он может некорректно отображать элементы управления вместо текста или чего-то еще.

Это должно иметь дело с этим лучшим способом - не уверен, из головы, будет ли предложенное вами исправление работать во всех сценариях.

0 голосов
/ 16 мая 2009

Да. Это ошибка в элементе управления Label.

...