Не понимая, почему ViewState не увеличивается в размере при изменении содержимого? - PullRequest
0 голосов
/ 04 июня 2011

Мне показалось, что я понял ViewState, но это немного странно.

У меня есть страница с 1000 надписями и текстовыми полями:

<dt>
   <asp:Label runat="server" ID="Label1" AssociatedControlID="TextBox1">Label1</asp:Label>
</dt>
<dd>
   <asp:TextBox runat="server" ID="TextBox1"></asp:TextBox>
</dd>

Все увеличивается на 1. Я добавил кнопку вверху:

<asp:Button runat="server" ID="PostBack" Text="Post it all back!" OnClick="ChangeValues"/>

и соответствующий код:

protected void ChangeValues(object sender, EventArgs e)
{
   for (int i = 1; i <= 1000; i++)
   {
      string textBoxId = "TextBox" + i;
      ((TextBox)Page.FindControl(textBoxId)).Text = textBoxId;
   }
}

Так что я бы понял:

  1. Загрузка первой страницы, элементы управления настроены изначально, поэтому состояние элемента управления не создано
  2. При обратной передаче, нажатие кнопки изменяет элементы управления. Поэтому при создании ViewState .NET понимает, что текст изменился по умолчанию, и записывает это в viewstate.

Теперь для 1000 элементов управления вы ожидаете, что он будет достаточно большим, намного большим, чем этот:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNjYzODc0MDE1ZGQRGHqYtZTbbkevIfg33I4Wja+xfz0at0+fDMS72BtZNA==" />

Я думаю, что мне здесь не хватает трюка. Я включил Trace=true и заметил, что все ViewState все еще 0 байтов. EnableViewState и ViewStateMode не объявлены в директиве <@Page, поэтому ViewState включен и работает.

Может кто-нибудь помочь мне понять, почему я неправильно понимаю, как это работает?

Ответы [ 2 ]

2 голосов
/ 04 июня 2011

Возможно, это связано с тем, что свойство Text для TextBox не нужно сохранять в ViewState, поскольку оно будет отображаться на странице и отправляться обратно с данными публикации.

Если вы посмотрите на реализацию TextBox с Reflector, вы увидите, что у нее есть свойство SaveTextViewState, которое определяет, нужно ли сохранять свойство Text в ViewState:

protected override object SaveViewState()
{
    if (!this.SaveTextViewState)
    {
        // This means the Text property will not be saved to ViewState
        this.ViewState.SetItemDirty("Text", false);
    }
    return base.SaveViewState();
}

В случаях, когда необходимо сохранение ViewState (например, TextBox невидим), SaveTextViewState возвращает значение true, а свойство Text сохраняется в ViewState.

UPDATE

Согласно Reflector реализация свойства SaveTextViewState (свойство, используемое для определения необходимости сохранения Text в ViewState) выглядит следующим образом:

private bool SaveTextViewState
{
    get
        {
            if (this.TextMode == TextBoxMode.Password) return false;
        }
        if (((base.Events[EventTextChanged] == null) && 
              base.IsEnabled) && 
              ((this.Visible && !this.ReadOnly)  && 
              (base.GetType() == typeof(TextBox))))
        {
            return false;
        }
        return true;
    }
}

т.е. Text сохраняется в ViewState, если это не текстовое поле пароля и выполняется любое из следующих действий:

  • существует обработчик для события TextChanged (в этом случае ему требуется исходное значение, чтобы определить, изменился ли текст)

  • элемент управления отключен (в этом случае текст не будет отправлен обратно)

  • элемент управления не отображается (в этом случае он не будет отображен)

  • элемент управления только для чтения (текст не будет отправлен обратно)

  • тип элемента управления не TextBox (не оптимизируйте, подавив ViewState, так как это может повлиять на реализацию производного элемента управления).

По сути, это оптимизация, которая подавляет ViewState, если она точно не нужна.

0 голосов
/ 05 июня 2011

Ответ: Элементы управления, которые реализуют IPostBackEventHandler, как Textbox, Checkbox и т. Д., Сохранят состояние even after disabling the viewstate.Причина в том, что на этапе загрузки данных обратной передачи эти элементы управления будут получать информацию о состоянии из формы «Отправлено обратно».

Но элементы управления, такие как метка, которые не реализуют IPostBackEventHandler, не будут получать никакой информации о состоянии из данных обратной передачи и, следовательно, полностью зависетьна viewstate для поддержания состояния.

...