views:

334

answers:

3

EDIT 2: Well, I went to the code. Note what they are doing here. They are saying load viewstate, and then turning around and setting the Text property to what was in the viewstate. After LoadViewState is called though viewstate tracking is on, and that results in the behavior I'm seeing. I think what the code should say is:

if (s != Text) {Text = s;}. That would get rid of the issue altogether and keep whatever invariant they need in place.

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

Edit: From all my tests this appears to only affect the Label control. I still think this is a bug.

This is an ASP.NET 3.5 Website.

Consider the following .aspx page: (html, head, body, etc. snipped)

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

The page has the following code behind:

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

Yes, that line is commented out. Coming to that. So, when you click the button you will see that viewstate is 52 bytes. Even though the label has lots of text, of course the way viewstate works is that it doesn't need to save the lots of text in the viewstate because the initial value of the Text property never changed. OK. So far so good. This is all expected behavior. In fact, even if the label contained 1 meg of text, the viewstate size would still be 52 bytes. OK. Now change the method to

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

It doesn't matter what property we change. Now click the button. ViewState size goes up to 92 bytes. Alright 40 bytes to store a one character access key, a little much if you ask me but whatever :) Now, click the button again. What's the viewstate size now? Should be 92 bytes right? No. It's 480. Clicking anymore and it stays at the 480 bytes size. What's happening? Changing the label property caused the label to start storing the label TEXT in the viewstate. What???? Stick a 100K of text in the label and you'll see the viewstate go up to ~100K.

Is this a bug? How is this possibly expected behavior?

+3  A: 

It doesn't just store the one character, it needs to store the property that it applies to too.

See http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx for more info on how viewstate works.

Although there may be ways in which viewstate may behave differntly to what you expect, there are unlikely to be any bugs as viewstate is central to the way ASP.NET works.

hopethisworks
I understand that it doesn't just store the one character. My snarky comment was not the main issue. And yes, the article you referenced is exactly what leads me to believe this is a bug:The article says:"WHAT DOES VIEWSTATE DO?2. Tracks changes to a ViewState value's initial state"But here, we are saying that a value's initial state is being SAVED when modifying ANOTHER properties initial state.
aquinas
It's probably saving the initial state of every property that isn't the default value of the control. In this case, the text property's default value is an empty string, so it saves your text...
uzbones
@uzbones - According to the article, the state of the text property should be what's set in the designer.
Greg
A: 

Yes. It's a bug in the Label control.

aquinas
A: 

ASP.NET dev here :) And author of the viewstate article mentioned.

Speaking as myself and not as MS, just to be clear. Yes -- this is a bug. To shed a little light though on why the code is setting the property when seemingly it is unnecessary (since the value is already stored in ViewState -- why set it which will just put it back in ViewState again?). If you look at the setter for Text, you'll see that in addition to setting the value into ViewState, it calls Controls.Clear(). This is because Label supports having child controls as it's 'text' as well as a literal string. If it didn't set the Text property in LoadViewState, then it might incorrectly render the controls instead of the text, or something.

It should deal with that in a better way -- not sure off the top of my head whether the proposed fix you mentioned would work in all scenarios.

InfinitiesLoop