开发者

Not understanding why ViewState is not increasing in size when changing content?

开发者 https://www.devze.com 2023-03-10 21:50 出处:网络
I thought I understood ViewState, but this is a bit of a weird one. I have a page of 1000 labels and textboxes like this:

I thought I understood ViewState, but this is a bit of a weird one.

I have a page of 1000 labels and textboxes like this:

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

All increme开发者_StackOverflow中文版ting by 1. I've added a button to the top:

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

and the corresponding code is:

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

So what I would understand is:

  1. First page load, the controls are set up initially, therefore no control viewstate created
  2. On postback, the button click is modifying the controls. Therefore, when generating the ViewState, .NET realises that the text has changed from the default and records this in the viewstate.

Now for 1000 controls, you'd expect it to be reasonably big, well bigger than this:

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

I think I'm missing a trick here. I have turned on Trace=true, and noticed that all of the ViewState is still 0 bytes. EnableViewState and ViewStateMode are not declared in the <@Page directive, so ViewState is on and working.

Can anyone help me understand why I am misunderstanding how this is working?


Perhaps it's because the Text property of a TextBox doesn't need to be saved to ViewState as it will be rendered to the page and posted back with the post data.

If you look at the implementation of TextBox with Reflector you'll see it has a property SaveTextViewState that controls whether the Text property needs to be saved to 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();
}

In cases where saving the ViewState is necessary (e.g. the TextBox is not Visible), SaveTextViewState returns true and the Text property is saved to ViewState.

UPDATE

According to Reflector the implementation of the SaveTextViewState property (the property used to determine whether Text needs to be persisted to ViewState) is as follows:

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;
    }
}

I.e. Text is persisted to ViewState if it's not a password textbox and any of the following are true:

  • there exists a handler for the TextChanged event (in this case it needs the original value to detect if the text has changed)

  • the control is disabled (in which case the Text won't be posted back)

  • the control is not visible (in which case it won't be rendered)

  • the control is readonly (Text won't be posted back)

  • the control type is not TextBox (don't optimize by suppressing ViewState as this may impact the implementation of a derived control).

Essentially an optimization that suppresses ViewState if it's sure it won't be needed.


The answer is Controls which implement IPostBackEventHandler like Textbox, Checkbox, etc. will retain the state even after disabling the viewstate. The reason is during the Load Postback Data stage, these controls will get state information from Posted back form.

But controls like label which do not implement IPostBackEventHandler will not get any state information from posted back data and hence depend entirely on viewstate to maintain the state.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号