Thursday, August 03, 2006 12:30 AM InfinitiesLoop

TRULY Understanding ViewState

ViewState is a very misunderstood animal. I would like to help put an end to the madness by attempting to explain exactly how the ViewState mechanism works, from beginning to end, and from many different use cases, such as declared controls vs. dynamic controls.

There are a lot of great articles out there that try to dispel the myths about ViewState. You might say this is like beating a dead horse (where ViewState is the horse, and the internet is the assailant). But this horse isn't dead, let me tell you. No, he's very much alive and he's stampeding through your living room. We need to beat him down once again. Don't worry, no horses were harmed during the authoring of this article.

It's not that there's no good information out there about ViewState, it's just all of them seem to be lacking something, and that is contributing to the community's overall confusion about ViewState. For example, one of the key features that is important to understand about ViewState is how it tracks dirtiness. Yet, here is a very good, in-depth article on ViewState that doesn't even mention it! Then there's this W3Schools article on ViewState that seems to indicate that posted form values are maintained via ViewState, but that's not true. (Don't believe me? Disable ViewState on that textbox in their example and run it again). And it's the #1 Google Search Result for "ASP.NET ViewState". Here is ASP.NET Documentation on MSDN that describes how Controls maintain state across postbacks. The documentation isn't wrong per say, but it makes a statement that isn't entirely correct:

"If a control uses ViewState for property data instead of a private field, that property automatically will be persisted across round trips to the client."

That seems to imply that anything you shove into the ViewState StateBag will be round-tripped in the client's browser. NOT TRUE! So it's really no wonder there is so much confusion on ViewState. There is no where I've found on the internet that has a 100% complete and accurate explanation of how it works! The best article I have ever found is this one by Scott Mitchell. That one should be required reading. However, it does not explain the relationship of controls and their child controls when it comes to initialization and ViewState Tracking, and it is this point alone that causes a bulk of the mishandlings of ViewState, at least in the experiences I've had.

So the point of this article will be to first give a complete understanding of how ViewState basically functions, from beginning to end, hopefully filling in the holes that many other articles have. After a complete explanation of the entire ViewState process, I will go into some examples of how developers typically misuse ViewState, usually without even realizing it, and how to fix it. I should also preface this with the fact that I wrote this article with ASP.NET 1.x in mind. However, there are very few differences in the ViewState mechanism in ASP.NET 2.0. For one, ControlState is a new type of ViewState in ASP.NET 2.0, but it treated exactly like ViewState, so we can safely ignore it for the purposes of this article.

First let me explain why I think understanding ViewState to it's core is so important:

    MISUNDERSTANDING OF VIEWSTATE WILL LEAD TO...
  1. Leaking sensitive data
  2. ViewState Attacks - aka the Jedi Mind Trick -- *waves hand* that plasma tv is for sale for $1.00
  3. Poor performance - even to the point of NO PERFORMANCE
  4. Poor scalability - how many users can you handle if each is posting 50k of data every request?
  5. Overall poor design
  6. Headache, nausea, dizziness, and irreversible frilling of the eyebrows.
If you develop an ASP.NET Application and you don't take ViewState seriously, this could happen to you:
ViewState Madness!!! Drop your red bull and surrender your cpu cycles. You will be frustrated. Performance is futile!
The ViewState form field. ViewState will add your web app's distinctiveness to it's own. Performance is futile.
I could go on but that is the gist of it. Now lets move on by starting back from the beginning:
    WHAT DOES VIEWSTATE DO?
    This is a list of ViewState's main jobs. Each of these jobs serves a very distinct purpose. Next we'll learn exactly how it fulfills those jobs.
  1. Stores values per control by key name, like a Hashtable
  2. Tracks changes to a ViewState value's initial state
  3. Serializes and Deserializes saved data into a hidden form field on the client
  4. Automatically restores ViewState data on postbacks
Even more important than understanding what it does, is understanding what it does NOT do:
    WHAT DOESN'T VIEWSTATE DO?
  1. Automatically retain state of class variables (private, protected, or public)
  2. Remember any state information across page loads (only postbacks) (that is unless you customize how the data is persisted)
  3. Remove the need to repopulate data on every request
  4. ViewState is not responsible for the population of values that are posted such as by TextBox controls (although it does play an important role)
  5. Make you coffee
While ViewState does have one overall purpose in the ASP.NET Framework, it's four main roles in the page lifecycle are quite distinct from each other. Logically, we can separate them and try to understand them individually. It is often the mishmash of information on ViewState that confuses people. Hopefully this breaks it down into more bite size nuggets. Mmmm... ViewState Nuggets.
ViewState Nuggets

1. VIEWSTATE STORES VALUES
If you've ever used a hashtable, then you've got it. There's no rocket science here. ViewState has an indexer on it that accepts a string as the key and any object as the value. For example:

ViewState["Key1"] = 123.45M; // store a decimal value
ViewState["Key2"] = "abc"; // store a string
ViewState["Key3"] = DateTime.Now; // store a DateTime

Actually, "ViewState" is just a name. ViewState is a protected property defined on the System.Web.UI.Control class, from which all server controls, user controls, and pages, derive from. The type of the property is System.Web.UI.StateBag. Strictly speaking, the StateBag class has nothing to do with ASP.NET. It happens to be defined in the System.Web assembly, but other than it's dependency on the State Formatter, also defined in System.Web.UI, there's no reason why the StateBag class couldn't live along side ArrayList in the System.Collections namespace. In practice, Server Controls utilize ViewState as the backing store for most, if not all their properties. This is true of almost all Microsoft's built in controls (ie, label, textbox, button). This is important! You must understand this about controls you are using. Read that sentance again. I mean it... here it is a 3rd time: SERVER CONTROLS UTILIZE VIEWSTATE AS THE BACKING STORE FOR MOST, IF NOT ALL THEIR PROPERTIES. Depending on your background, when you think of a traditional property, you might imagine something like this:

public string Text {
    get { return _text; }
    set { _text = value; }
}

What is important to know here is that this is NOT what most properties on ASP.NET controls look like. Instead, they use the ViewState StateBag, not a private instance variable, as their backing store:

public string Text {
    get { return (string)ViewState["Text"]; }
    set { ViewState["Text"] = value; }
}

And I can't stress it enough -- this is true of almost ALL PROPERTIES, even STYLES (actually, Styles do it by implementing IStateManager, but essentially they do it the same way). When writing your own controls it would usually be a good idea to follow this pattern, but thought should first be put into what should and shouldn't be allowed to be dynamically changed on postbacks. But I digress -- that's a different subject. It is also important to understand how DEFAULT VALUES are implemented using this technique. When you think of a property that has a default value, in the traditional sense, you might imagine something like the following:

public class MyClass {
    private string _text = "Default Value!";
 
    public string Text {
        get { return _text; }
        set { _text = value; }
    }
}

The default value is the default because it is what is returned by the property if no one ever sets it. How can we accomplish this when ViewState is being used as the private backing? Like this:

public string Text {
    get {
        return ViewState["Text"] == null ?
             "Default Value!" :
              (string)ViewState["Text"];
    }
    set { ViewState["Text"] = value; }
}

Like a hashtable, the StateBag will return null as the value behind a key if it simply doesn't contain an entry with that key. So if the value is null, it has not been set, so return the default value, otherwise return whatever the value is. For you die-hards out there -- you may have detected a difference in these two implementations. In the case of ViewState backing, setting the property to NULL will result in resetting the property back to it's default value. With a "regular" property, setting it to null means it will simply be null. Well, that is just one reason why ASP.NET always tends to use String.Empty ("") instead of null. It's also not very important to the built in controls because basically all of their properties that can be null already are null by default. All I can say is keep this in mind if you write your own controls. And finally, as a footnote really, while this property-backing usage of the ViewState StateBag is how the StateBag is typically used, it isn't limited to just that. As a control or page, you can access you're own ViewState StateBag at any time for any reason, not just in a property. It is sometimes useful to do so in order to remember certain pieces of data across postbacks, but that too is another subject.

2. VIEWSTATE TRACKS CHANGES
Have you ever set a property on a control and then somehow felt... dirty? I sure have. In fact, after a twelve-hour day of setting properties in the office, I become so filthy my wife refuses to kiss me unless I'm holding flowers to mask the stench. I swear! Ok so setting properties doesn't really make you dirty. But it does make the entry in the StateBag dirty! The StateBag isn't just a dumb collection of keys and values like a Hashtable (please don't tell Hashtable I said that, he's scarey). In addition to storing values by key name, the StateBag has a TRACKING ability. Tracking is either on, or off. Tracking can be turned on by calling TrackViewState(), but once on, it cannot be turned off. When tracking is ON, and ONLY when tracking is ON, any changes to any of the StateBag's values will cause that item to be marked as "Dirty". StateBag even has a method you can use to detect if an item is dirty, aptly named IsItemDirty(string key). You can also manually cause an item to be considered dirty by calling SetItemDirty(string key). To illustrate, lets assume we have a StateBag that is not currently tracking:

stateBag.IsItemDirty("key"); // returns false
stateBag["key"] = "abc";
stateBag.IsItemDirty("key"); // still returns false
 
stateBag["key"] = "def";
stateBag.IsItemDirty("key"); // STILL returns false
 
stateBag.TrackViewState();
stateBag.IsItemDirty("key"); // yup still returns false
 
stateBag["key"] = "ghi";
stateBag.IsItemDirty("key"); // TRUE!
 
stateBag.SetItemDirty("key", false);
stateBag.IsItemDirty("key"); // FALSE!

Basically, tracking allows the StateBag to keep track of which of it's values have been changed since TrackViewState() has been called. Values that are assigned before tracking is enabled are not tracked (StateBag turns a blind eye). It is important to know that any assignment will mark the item as dirty -- even if the value given matches the value it already has!

stateBag["key"] = "abc";
stateBag.IsItemDirty("key"); // returns false
stateBag.TrackViewState();
stateBag["key"] = "abc";
stateBag.IsItemDirty("key"); // returns true

ViewState could have been written to compare the new and old values before deciding if the item should be dirty. But recall that ViewState allows any object to be the value, so you aren't talking about a simple string comparison, and the object doesn't have to implement IComparable so you're not talking about a simple CompareTo either. Alas, because serialization and deserialization will be occuring, an instance you put into ViewState won't be the same instance any longer after a postback. That kind of comparison is not important for ViewState to do it's job, so it doesn't. So that's tracking in a nutshell.

But you might wonder why StateBag would need this ability in the first place. Why on earth would anyone need to know only changes since TrackViewState() is called? Why wouldn't they just utilize the entire collection of items? This one point seems to be at the core of all the confusion on ViewState. I have interviewed many professionals, sometimes with years and years of ASP.NET experience logged in their resumes, who have failed miserably to prove to me that they understand this point. Actually, I have never interviewed a single candidate who has! First, to truly understand why Tracking is needed, you will need to understand a little bit about how ASP.NET sets up declarative controls. Declarative controls are controls that are defined in your ASPX or ASCX form. Here:

<asp:Label id="lbl1" runat="server" Text="Hello World" />

I do declare that this label is declared on your form. The next thing we need to make sure you understand is ASP.NET's ability to wire up declared attributes to control properties. When ASP.NET parses the form, and finds a tag with runat=server, it creates an instance of the specified control. The variable name it assigns the instance to is based on the ID you assigned it (by the way, many don't realize that you don't have to give a control an ID at all, ASP.NET will use an automatically generated ID. Not specifying an ID has advantages, but that is a different subject). But that's not all it does. The control's tag may contain a bunch of attributes on it. In our label example up above, we have a "Text" attribute, and it's value is "Hello World". Using reflection, ASP.NET is able to detect whether the control has property by that name, and if so, sets its value to the declared value. Obviously the attribute is declared as a string (hey, its stored in a text file after all), so if the property it maps to isn't of type string, it must figure out how to convert the given string into the correct type, before calling the property setter. How it does that my friend is also an entirely different topic (it involves TypeConverters and static Parse methods). Suffice it to say it figures it out, and calls the property setter with the converted value.

Recall that all-important statement from the first role of the StateBag. Here it is again: Server Controls utilize ViewState as the backing store for most, if not all their properties. That means when you declare an attribute on a server control, that value is usually ultimately stored as an entry in that control's ViewState StateBag. Now recall how tracking works. Remember that if the StateBag is "tracking", then setting a value to it will mark that item as dirty. If it isn't tracking, it won't be marked dirty. So the question is -- when ASP.NET calls the SET on the PROPERTY that corresponds to the ATTRIBUTE that is DECLARED on the control, is the StateBag TRACKING or isn't it? The answer is no it is not tracking, because tracking doesn't begin until someone calls TrackViewState() on the StateBag, and ASP.NET does that during the OnInit phase of the page/control lifecycle. This little trick ASP.NET uses to populate properties allows it to easily detect the difference between a declaratively set value and dynamically set value. If you don't yet realize why that is important, please keep reading.

3. SERIALIZATION AND DESERIALIZATION
Aside from how ASP.NET creates declarative controls, the first two capabilities of ViewState we've discussed so far have been strictly related to the StateBag class (how it's similar to a hashtable, and how it tracks dirty values). Here is where things get bigger. Now we will have to start talking about how ASP.NET uses the ViewState StateBag's features to make the (black) magic of ViewState happen.

If you've ever done a "View Source" on an ASP.NET page, you've no doubt encountered the serialization of ViewState. You probably already knew that ViewState is stored in a hidden form field aptly named _ViewState as a base64 encoded string, because when anyone explains how ViewState works, that's usually the first thing they mention.

A brief aside -- before we understand how ASP.NET comes up with this single encoded string, we must understand the hierarchy of controls on the page. Many developers with years of experience still don't realize that a page consists of a tree of controls, because all they work on are ASPX pages, and all they need to worry about are controls that are directly declared on those pages... but controls can contain child controls, which can contain their own child controls, etc. This forms a tree of controls, where the ASPX page itself is the root of that tree. The 2nd level is all the controls declared at the top level in the ASPX page (usually that consists of just 3 controls -- a literal control to represent the content before the form tag, a HtmlForm control to represent the form and all its child controls, and another literal control to represent all the content after the close form tag). On the 3rd level are all the controls contained within those controls (ie, controls that are declared within the form tag), and so on and so forth. Each one of the controls in the tree has it's very own ViewState -- it's very own instance of a StateBag. There's a protected method defined on the System.Web.UI.Control class called SaveViewState. It returns type 'object'. The implementation for Control.SaveViewState is to simply pass the call along to the Control's StateBag (it too has a SaveViewState() method). By calling this method recursively on every control in the control tree, ASP.NET is able to build another tree that is structured not unlike the control tree itself, except instead of a tree of controls, it is a tree of data.

The data at this point is not yet converted into the string you see in the hidden form field, it's just an object tree of the data to be saved. Here is where it finally comes together... are you ready? When the StateBag is asked to save and return it's state (StateBag.SaveViewState()), it only does so for the items contained within it that are marked as Dirty. That is why StateBag has the tracking feature. That is the only reason why it has it. And oh what a good reason it is -- StateBag could just process every single item stored within it, but why should data that has not been changed from it's natural, declarative state be persisted? There's no reason for it to be -- it will be restored on the next request when ASP.NET reparses the page anyway (actually it only parses it once, building a compiled class that does the work from then on). Despite this smart optimization employed by ASP.NET, unnecessary data is still persisted into ViewState all the time due to misuse. I will get into examples that demonstrate these types of mistakes later on.

POP QUIZ
If you've read this far, congratulations, I am rewarding you with a pop quiz. Aren't I nice? Here it is: Let's say you have two nearly identical ASPX forms: Page1.aspx and Page2.aspx. Contained within each page is just a form tag and a label, like so:

<form id="form1" runat="server">
    <asp:Label id="label1" runat="server" Text="" />
</form>

They are identical except for one minor difference. In Page1.aspx, we shall declare the label's text to be "abc":

<asp:Label id="label1" runat="server" Text="abc" />

...And on Page2.aspx, we shall declare the label's text to be something much longer (the preamble to the Constitution of the United States of America):

<asp:Label id="label1" runat="server" Text="We the people of the United States,
        in order to form a more perfect union, establish justice, insure
        domestic tranquility, provide for the common defense, promote the
        general welfare, and secure the blessings of liberty to ourselves and
        our posterity, do ordain and establish this Constitution for the United
        States of America." />


Imagine you browse to Page1.aspx, you will see "abc" and nothing more. Then you use your browser to view the HTML source of the page. You will see the infamous hidden _ViewState hidden field with encoded data in it. Note the size of that string. Now you browse to Page2.aspx, and you see the preamble. You use your browser to view the HTML source once again, and you note the size of the encoded _ViewState field. The question is: Are the two sizes you noted the same, or are they different? Before we get to the answer, lets make it a little bit more involved. Lets say you also put a button next to the label (on each page):

<asp:Button id="button1" runat="server" Text="Postback" />


There is no code in the click event handler for this button, so clicking on it doesn't do anything except make the page flicker. With this new button in place, you repeat the experiment, except this time when browsing to each page, you click the Postback button before looking at the HTML source. So the question is once again... Are the encoded ViewState values the same, or different? The correct answer to the first part the question is THEY ARE THE SAME! They are the same because in neither of the two ViewState strings are any data related to the label at all. If you understand ViewState, this is obvious. The Text property of the label is set to the declared value before it's ViewState is being tracked. That means if you were to check the dirty flag of the Text item in the StateBag, it would not be marked dirty. StateBag ignores items that aren't dirty when SaveViewState() is called, and it is the object it returns that is serialized into the hidden _ViewState field. Therefore, the text property is not serialized. Since the Text is not serialized in either case, and the forms are identical in every other way, the sizes of the encoded ViewStates on each page must be the same. In fact, no matter how large or small of a string you stuff into that text attribute, the size will remain the same.

The correct answer to the second part is again, THEY ARE THE SAME! In order for data to be serialized, it must be marked as dirty. In order to be marked as dirty, it's value must be set after TrackViewState() is called. But even when we perform a postback, ASP.NET recreates and populates the server controls in the same way. The Text property is still set to it's declared value just like it was in the first request. No other code is setting the text property, so there's no way the StateBag item could become dirty, even on a postback. Therefore, the sizes of the encoded ViewStates on each page after a postback must be the same.

So now we understand how ASP.NET determines what data needs to be serialized. But we don't know how it is serialized. That topic is outside the scope of this article (are you missing an assembly reference?), so if you're really interested in how it works, read up on the LosFormatter for ASP.NET 1.x or the ObjectStateFormatter for ASP.NET 2.0.

Finally on this topic is DESERIALIZATION. Obviously all this fancy dirty tracking and serialization wouldn't do any good if we couldn't get the data back again. That too is outside the scope of this article, but suffice it to say the process is just the reverse. ASP.NET rebuilds the object tree it serialized by reading the posted _ViewState form value and deserializing it with the LosFormatter (v1.x) or the ObjectStateFormatter (v2.0).

4. AUTOMATICALLY RESTORES DATA
This is last on our list of ViewState features. It is tempting to tie this feature in with Deserialization above, but it is not really part of that process. ASP.NET deserializes the ViewState data, and THEN it repopulates the controls with that data. Many articles out there confuse these two processes.

Defined on System.Web.UI.Control (again, the class that every control, user control, and page derive from) is a LoadViewState() method which accepts an object as parameter. This is the opposite of the SaveViewState() method we already discussed, which returns an object. Like SaveViewState(), LoadViewState() simple forwards the call on to it's StateBag object, calling LoadViewState on it. The StateBag then simply repopulates it's key/object collection with the data in the object. In case you are wondering, the object it is given is a System.Web.UI.Pair class, which is just a simple type with a First and Second field on it. The "First" field is an ArrayList of key names, and the "Second" field is an ArrayList of values. So StateBag just iterates over the lists, calling this.Add(key, value) for each item. The important thing to realize here is that the data it was given via LoadViewState() are only items that where marked dirty on the previous request. Prior to loading the ViewState items, the StateBag may already have values in it. Those values may be from declarative properties like we discussed, but they may also be values that were explicitly set by the developer prior to the LoadViewState call. If one of the items passed into LoadViewState already exists in the StateBag for some reason, it will be overwritten.

That right there is the magic of automatic state management. When the page first begins to load during a postback (even prior to initialization), all the properties are set to their declared natural defaults. Then OnInit occurs. During the OnInit phase, ASP.NET calls TrackViewState() on all the StateBags. Then LoadViewState() is called with the deserialized data that was dirty from the previous request. The StateBag calls Add(key, value) for each of those items. Since the StateBag is tracking at this point, the value is marked dirty, so that it may be persisted once again for the next postback. Brilliant! Whew. Now you are an expert on ViewState management.

IMPROPER USE OF VIEWSTATE
Now that we know exactly how ViewState works, we can finally begin to understand the problems that arise when it is used improperly. In this section I will describe cases that illustrate how a lot of ASP.NET developers misuse ViewState. But these aren't just obvious mistakes. Some of these will illustrate nuances about ViewState that will give you an even deeper understanding of how it all fits together.
    CASES OF MISUSE
  1. Forcing a Default
  2. Persisting static data
  3. Persisting cheap data
  4. Initializing child controls programmatically
  5. Initializing dynamically created controls programmatically
1. Forcing a Default
This is one of the most common misuses, and it is also the easiest to fix. The fixed code is also usually more compact than the wrong code. Yes, doing things the right way can lead to less code. Imagine that. This usually occurs when a control developer wants a particular property to have a particular default value, and does not understand the dirty tracking mechanism, or doesn't care. For example, lets say the Text property a control is supposed to be some value that comes from a Session variable. Developer Joe writes the following code:

public class JoesControl : WebControl {
    public string Text {
        get { return this.ViewState["Text"] as string; }
        set { this.ViewState["Text"] = value; }
    }
 
    protected override void OnLoad(EventArgs args) {
        if(!this.IsPostback) {
            this.Text = Session["SomeSessionKey"] as string;
        }
 
        base.OnLoad(e);
    }
}

This developer has committed a ViewState crime, call the ViewState police! There's two big problems with this approach. First of all, since Joe is developing a control, and he has taken the time to create a public Text property, it stands to reason that Joe may want developers that use his control to be able to set the Text property to something else. Jane is a page developer that is attempting to do just that, like so:

<abc:JoesControl id="joe1" runat="server" Text="ViewState rocks!" />

Jane is going to have a bad day. No matter what Jane puts into that Text attribute, Joe's control will refuse to listen to her. Poor Jane. She's using this control just like you use every other ASP.NET control, but this one works differently. Joe's control is overwriting Jane's Text value! Worse than that, since Joe sets it during the OnLoad phase, it is marked dirty in ViewState. So to add insult to injury, Jane is now incurring an increase in her page's serialized ViewState size for doing nothing more than putting Joe's Control on her page. I guess Joe doesn't like Jane very much. Maybe Joe's just trying to get back at Jane for something. Well, since we all know which sex rules this world, we can assume Jane ends up getting Joe to fix his control. Much to Jane's delight, this is what Joe comes up with:

public class JoesControl : WebControl {
    public string Text {
        get {
            return this.ViewState["Text"] == null ?
                Session["SomeSessionKey"] :
                this.ViewState["Text"] as string;
        }
        set { this.ViewState["Text"] = value; }
    }
}

Look at how much less code we have here. Joe doesn't even have to override OnLoad. Because the StateBag returns null if the given key does not exist, Joe can detect whether his Text property has been set already by checking for null. If it is, he can safely return his would-be default value. If it's not null, he happily returns whatever value it is. Simple as can be. Now when Jane uses Joe's control, not only is her Text attribute honored, she no longer incurs a hit on her ViewState size, either. Better behavior. Better performance. Less code. Everyone wins!

2. Persisting static data
By Static, I mean data that never changes or is not expected to change during the lifetime of a page, or even during the users session. Lets say Joe, our would-be shoddy asp.net developer, has been tasked with adding the current user's name to the top of a page in the company's eCommerce application. It's a nice way of telling the user, "hey, we know who you are!" It makes them feel special and that the site is working. Positive feedback. Lets say this eCommerce application has a business layer API that allows Joe to easily get the name of the currently authenticated user: CurrentUser.Name. Joe completes his task:

(ShoppingCart.aspx)
<asp:Label id="lblUserName" runat="server" />


(ShoppingCart.aspx.cs)
protected override void OnLoad(EventArgs args) {
    this.lblUserName.Text = CurrentUser.Name;
    base.OnLoad(e);
}

Sure enough, the current user's name will show up. Piece of cake, Joe thinks. Of course we know Joe has committed another sin. The label control he is using is tracking it's ViewState when it is assigned the current user's name. That means not only will the Label render the user name, but that user name will be encoded into the ViewState hidden form field. Why make ASP.NET go through all the work of serializing and deserializing the user name, when you are just going to reassign it after all? That's just rude! Even when confronted, Joe shrugs at the problem. It's only a few bytes! But it's a few bytes you can save so easily. There are two solutions to this problem. First... you could just disable ViewState on the label.

<asp:Label id="lblUserName" runat="server" EnableViewState="false" />

Problem solved. But there's an even better solution. Label has to be one of the most overused controls there are, bested only by the Panel control. It comes from the mindset of Visual Basic Programmers. To show text on a VB Form you needed a label. Labels are supposed to be the ASP.NET WebForm counterpart, so it's only nature to think you need a label to display a text value that isn't hardcoded in the webform. Fair enough, but that's not true. Label's render a <span> tag around their text content. You must ask yourself whether your really need this span tag at all. Unless you are applying a STYLE to this label, the answer is NO. This would suffice just fine:

<%= CurrentUser.Name %>

Not only do you get to avoid having to declare a label on the form (which means less code, albeit designer-generated code), but you've followed the spirit of the code-behind model: separation of code from design! In fact, if Joe's company had a dedicated designer responsible for the look and feel of the eCommerce site, Joe could have simply passed on the task. "That's the designers job", he could have balked, and rightfully so. There is another reason why you might THINK you need a Label, and that is when something in the code behind may need to programmatically access or manipulate that label. Ok, fair enough. But you must still ask yourself whether you really need a SPAN tag surrounding the text. Introducing the most underused control in ASP.NET: The LITERAL!

<asp:Literal id="litUserName" runat="server" EnableViewState="false"/>

No span tag here.

3. Persisting cheap data
This one is a superset of #2. Static data is definitely cheap to get. But not all cheap data is static. Sometimes we have data that may change during the lifetime of an application, possibly from moment to moment, but that data is virtually free to retrieve. By free, I mean the performance cost of looking it up is insignificant. A common instance of this mistake is when populating a dropdown list of U.S. States. Unless you are writing a web application that you plan on warping back in time to December 7, 1787 (here), the list of US States is not going to change any time soon. However, as a programmer that hates to type, you certainly wouldn't want to have to type these states by hand into your web form. And in the event a state does rebel (we can only dream... you know who you are), you wouldn't want to have to perform a code change to strike it from the list. Our proverbial programmer Joe decides he will populate his dropdown list from a USSTATES table in a database. The eCommerce site is already using a database, so its trivial for him to add the table and query it.

<asp:DropdownList id="lstStates" runat="server"
    DataTextField="StateName" DataValueField="StateCode" />

protected override void OnLoad(EventArgs args) {
    if(!this.IsPostback) {
        this.lstStates.DataSource = QueryDatabase();
        this.lstStates.DataBind();
    }
    base.OnLoad(e);
}

As is the nature of databound controls in ASP.NET, the state dropdown will be using ViewState to remember it's databound list of list items. At the time of this ranting, there are a total of 50 US States. Not only does the dropdown list contain a ListItem for each and every state, but each and every one of those states and their state codes are being serialized into the encoded ViewState. That's a lot of data to be stuffing down the pipe every time the page loads, especially over a dialup connection. I often wonder what it would be like if I explained to my grandmother the reason why her internet is so slow is because her computer is telling the server what all the US States are. I don't think she'd understand. She'd probably just start explaining how when she was young, there were only 46 states. Too bad... those extra 4 states are really wearing down your bandwidth. Damn you late comers! You know who you are!

Like the problem with static data, the general solution to this problem is to just disable ViewState on the control. Unfortunately, that is not always going to work. Whether it does depends on the nature of the control you are binding, and what features of it you are dependant on. In this example, if Joe simply added EnableViewState="false" to the dropdown, and removed the if(!this.IsPostback) condition, he would successfully remove the state data from ViewState, but he would immediately run into a troubling problem. The dropdown will no longer restore it's selected item on postbacks. WAIT!!! This is another source of confusion with ViewState. The reason the dropdown fails to remember it's selected item on postbacks is NOT because you have disabled ViewState on it. Postback controls such as dropdownlist and textbox restore their posted state (the selected item of a dropdown ist 'posted') even when ViewState is disabled, because even with ViewState disabled the control is still able to post its value. It forgets it's selected value because you are rebinding it in OnLoad, which is after the dropdown has already loaded it's posted value. When you databind it again, the first thing it does is throw that into the bit bucket (you know, digital trash). That means if a user selects California from the list, then click on a submit button, the dropdown will stubbornly return the default item (the first item if you don't specify it otherwise). Thankfully, there is an easy solution: Move the DataBind into OnInit:

<asp:DropdownList id="lstStates" runat="server"
    DataTextField="StateName" DataValueField="StateCode" EnableViewState="false" />

protected override void OnInit(EventArgs args) {
    this.lstStates.DataSource = QueryDatabase();
    this.lstStates.DataBind();
    base.OnInit(e);
}

The short explanation for why this works: You are populating the dropdown list with items before it attempts to load it's posted value. Now the dropdown will behave just like it did when Joe first designed it, only the rather large list of states will NOT be persisted into the ViewState hidden field! Brilliant! More importantly, this rule applies to any data that is cheap and easy to get to. You might argue that making a database query on every request is MORE costly than persisting the data through ViewState. In this case I believe you'd be wrong. Modern database systems (say, SQL Server) have sophisticated caching mechanism and are extremely efficient if configured correctly. The state list needs to be repopulated on every request no matter what you're doing. All you've done is change it from being pushed and pulled down a slow, unreliable 56kbps internet connection that may have to travel for thousands of miles, to being pulled over at worse a 10 megabit LAN connection a couple hundred feet between your internet server and database server. AND if you really wanted to improve things, you could cache the results of the database query in the application. You do the math!

4. Initializing child controls programmatically
Let's face it. You can't do everything declaratively. Sometimes you have to get logic involved. That's why we all have jobs, right? The trouble is ASP.NET does not provide an easy way to programmatically initialize properties of child controls correctly. You can override OnLoad and do it there -- but then you're persisting data that probably doesn't need to be persisted into ViewState. You can override OnInit and do it there instead, but that suffers from the same problem. Remember when we learned how ASP.NET calls TrackViewState() during the OnInit phase? It does this recursively on the entire control tree, but it does it from the BOTTOM of the tree UP! In other words, as a control or webform, the OnInit phase of your child controls occurs BEFORE your own. A control will begin tracking ViewState changes in this phase, which means by the time your own OnInit phase begins, your child controls ViewState are all already tracking! Lets say Joe would like to display the current date and time in a label declared on the form.

<asp:Label id="lblDate" runat="server" />

protected override void OnInit(EventArgs args) {
    this.lblDate.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
    base.OnInit(e);
}

Even though Joe is setting the label text in the earliest event possible on his webform, it's already too late. The label is tracking ViewState changes, and the current date and time will inevitably be persisted into ViewState. This particular example could fall under the cheap data issue above. Joe could simply disable ViewState on the label to solve this problem. But here we are going to solve it a different way in order to illustrate an important concept. What would be nice is if Joe could declaratively set the label text to what he wants, something like:

<asp:Label id="Label1" runat="server" Text="<%= DateTime.Now.ToString() %>" />

You may have intuitively attempted this before. But ASP.NET will slap you in the face for it. The "<%= %>" syntax can not be used to assign values to properties of server-side controls. Joe could use the "<%# %>" syntax instead, but that isn't very different than the databinding method we've already covered (disabling ViewState and databinding it every request). The problem is we would like to be able to assign a value through code, but allow the control to continue to work in exactly the way it normally would. Perhaps some code is going to be manipulating this label, and we want any changes made to it to be persisted through ViewState like they normally would be. For example, maybe Joe wants to give the users a way to remove the date display from the form, replacing it with a blank date instead:

private void cmdRemoveDate_Click(object sender, EventArgs args) {
    this.lblDate.Text = "--/--/---- --:--:--";
}

If the user clicks this button, the current date and time will vanish. But if we solved our original ViewState problem by disabling ViewState on the label, the date and time will magically reappear again on the next postback that occurs, because the label's ViewState being disabled means it will not automatically be restored. That's not good. What on Earth is Joe supposed to do now?

What we really want is to declaratively set a value that is based on logic, not static. If it were declared the label could continue to work like it normally does -- the initial state wouldn't be persisted since it is set before ViewState is tracking, and changes to it would be persisted in ViewState. Like I said... ASP.NET does not provide an easy way to accomplish this task. For you ASP.NET 2.0 developers out there, you do have the $ sign syntax, which allows you to use expression builders to declare values that actually come from a dynamic source (ie, resources, declared connection strings). There's no expression builder for "just run this code" so I don't think that helps you either (UPDATE: Unless you use my custom CodeExpressionBuilder!). Also for ASP.NET 2.0 developers, there's OnPreInit. That is actually a great place to initialize child control properties programmatically because it occurs before the child control's OnInit (and therefore before it is tracking ViewState) and after the controls are created. However, OnPreInit is not recursive like the other control phase methods are. That means it is only accessible on the PAGE itself. That doesn't help you what-so-ever if you are developing a CONTROL. It's too bad OnPreInit isn't recursive just like OnInit, OnLoad, and OnPreRender are, I don't see a reason for the inconsistency. The root of the problem is simply that we need to be able to assign the Text property of the label BEFORE it begins tracking its ViewState. We already know the page's OnInit event (the first event that occurs in the page) is already too late for that. So what if we could somehow hook into the Init event of the label? You can't add an event handler in code for that, because the soonest you can do it is in your OnInit which is after the source event has already occurred. And you can't do it in the constructor for the page, because declared controls are not yet created at that point. There are two possibilities:

1. Declaratively hook into the Init event:
<asp:Label id="Label2" runat="server" OnInit="lblDate_Init" />

This works because the OnInit attribute is processed before the label's own OnInit event occurs, giving us an opportunity to manipulate it before it beings tracking ViewState changes. Our event handler would set its text.

2. Create a custom control:
public class DateTimeLabel : Label {
    public DateTimeLabel() {
        this.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
    }
}

Then instead of a regular label on the form, a DateTimeLabel is used. Since the control is initializing it's own state, it can do so before tracking begins. It does it during the constructor if possible, so that a declared value will be honored.

5. Initializing dynamically created controls programmatically
This is the same problem as before, but since you are in more control of the situation, it is much easier to solve. Lets say Joe has written a custom control that at some point is dynamically creating a Label.

public class JoesCustomControl : Control {
    protected override void CreateChildControls() {
        Label l = new Label();
 
        this.Controls.Add(l);
        l.Text = "Joe's label!";
    }
}

Hmmm. When do dynamically created controls begin tracking ViewState? You can create and add dynamically created controls to your controls collection at almost any time during the page lifecycle, but ASP.NET uses the OnInit phase to start ViewState tracking. Won't our dynamic label miss out on that event? No. The trick is, Controls.Add() isn't just a simple collection add request. It does much more. As soon as a dynamic control is added to the control collection of a control that is rooted in the page (if you follow its parent controls eventually you get to the page), ASP.NET plays "catch up" with the event sequence in that control and any controls it contains. So let's say you add a control dynamically in the OnPreRender event (although there plenty of reasons why you would not want to do that). At that point, your OnInit, LoadViewState, LoadPostBackData, and OnLoad events have transpired. The second the control enters your control collection, all of these events happen within the control.

That means my friends the dynamic control is tracking ViewState immediately after you add it. Besides your constructor, the earliest you can add dynamic controls is in OnInit, where child controls are already tracking ViewState. In Joe's control, he's adding them in the CreateChildControls() method, which ASP.NET calls whenever it needs to make sure child controls exist (when it is called can vary based on whether you are an INamingContainer, whether it is a postback, and whether anything else calls EnsureChildControl()). The latest this can happen is OnPreRender, but if it happens any time after or during OnInit, you will be dirtying ViewState again, Joe. The solution is simple but easy to miss:

public class JoesCustomControl : Control {
    protected override void CreateChildControls() {
        Label l = new Label();
        l.Text = "Joe's label!";
 
        this.Controls.Add(l);
    }
}

Subtle. Instead of initializing the label's text after adding it to the control collection, Joe initializes it before it is added. This ensures without a doubt that the Label is not tracking ViewState when it is initialized. Actually you can use this trick to do more than just initialize simple properties. You can databind controls even before they are part of the control tree. Remember our US State dropdown list example? If we can create that dropdown list dynamically, we can solve that problem without even disabling its ViewState:

public class JoesCustomControl : Control {
    protected override void OnInit(EventArgs args) {
        DropDownList states = new DropDownList();
        states.DataSource = this.GetUSStatesFromDatabase();
        states.DataBind();
 
        this.Controls.Add(states);
    }
}


It works amazingly well. The dropdown list will behave as if the states are simply built-in list items. They are not persisted in ViewState, yet ViewState is still enabled on the control, meaning you can still take advantage of its ViewState dependant features like the OnSelectedIndexChanged event. You can even do this with DataGrids, although that depends on how you are using it (you will run into problems if you are using sorting, paging, or using the SelectedIndex feature).

BE VIEWSTATE FRIENDLY
Now that you have a complete understanding of how ViewState does it's magic, and how it interacts with the page lifecycle in asp.net, it should be easy to be ViewState Friendly! That is the key really... ViewState optimization is easy as pie when you understand what is going on, often times resulting in even less code than the non-friendly code. Have any suggestions, comments, error reports? Please leave a comment or send me an email!

UPDATE 02/19/2008: Take a look at TRULY Understanding ViewState, the Comment Index!

Filed under: , ,

Comments

# All about ViewState

Thursday, August 03, 2006 10:23 AM by Tim Mitchell :: Explore Your Inner Geek

Everything you ever wanted to know about ViewState ...

# TRULY Understanding ViewState

Thursday, August 03, 2006 7:05 PM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# Interesting Finds: August 2

Thursday, August 03, 2006 11:26 PM by Jason Haley

# Link Listing - August 3, 2006

Thursday, August 03, 2006 11:30 PM by Christopher Steen

TRULY Understanding ViewState [Via: InfinitiesLoop ] How-Do-I Video - Using the Atlas...

# Truly Understanding View State - Get really really to know ASP.Net ViewState

Thursday, August 10, 2006 2:30 AM by Lazy Coder

"WHAT DOES VIEWSTATE DO?This is a list of ViewState's main jobs. Each of these jobs serves a very distinct...

# re: TRULY Understanding ViewState

Thursday, August 10, 2006 10:45 AM by sclough

Thanks for taking time to write this, it really helped to clear up some problems I was having getting an understanding of what ViewState was doing. I'd also be grateful if the page rendered correctly in Firefox, it was annoying having to fire up IE to read it :^).

# re: TRULY Understanding ViewState

Sunday, August 13, 2006 7:03 AM by rekna

"ViewState is not responsible for the population of values that are posted such as by TextBox" DOT.NET 1.1 Suppose I have 2 user controls (let's call them G and F) on a page one containing a gridview one containing some textboxes. G is visible , F is not. When linkbutton detail in grid is clicked, G becomes invisible, F becomes visible and loads data (using databinding) for the selected row. Click save and G becomes visible, F invisible. Click New button on G, then G becomes invisible, F visible, there is NO databinding, so I would have expected empty textboxes in F, but previous values show up. These values could not have come from POSTing data, as the F control was invisible, and thus was not rendered. So values of textboxes on a control that is invisible are stored in ViewState ?

# re: TRULY Understanding ViewState

Monday, August 14, 2006 2:56 AM by Jouni Heikniemi

An interesting article! Shorter paragraphs and fewer attempts at humor would make it much more readable though. One thing I'd like to challenge you on is your advice on using OnInit to avoid dirtying the ViewState when initializing the States example (chapter 3 of the misuse part). Right after that in chapter 4 you state that initializing the formatted DateTime in OnInit is too late, since the label is already tracking its ViewState. There is apparent controversy between these two chapters. What are your thoughts on this, and what have you intended to say in chapter 3?

# re: TRULY Understanding ViewState

Monday, August 14, 2006 12:22 PM by InfinitiesLoop

sclough -- It should look fine in FF now, thanks for the heads up. I had just spent a few hours tweaking the UI and didn't get a chance to review it in FF. At least you were polite about it. You wouldn't believe some of the mail I got from FF users. Chill out guys :) It's not a war. Its a browser.

# re: TRULY Understanding ViewState

Monday, August 14, 2006 12:27 PM by InfinitiesLoop

rekna -- yes exactly. ViewState is important in a textbox if you want its value to be maintained even if the textbox is not visible for a while. It's also important if you want to use the TextChanged event since the way it knows whether the event should fire is by comparing its posted value to its viewstate value. Without ViewState it will always think it has changed (unless the value is blank) and so will always fire the event.

That being said, its still primarily the POST nature of the control that maintains its value. Thats why when you disable viewstate, it will still recall its value on a postback.

In 2.0 (not entirely sure if this is true of 1.1 but I think so) -- the textbox tries to be smarter about whether viewstate should be utilized. If you don't hook into the TextChanged event, the TextBox isn't "disabled" (to appear greyed out), and it is Visible, then there's no reason to pollute viewstate, and so it doesn't... automatically.

# re: TRULY Understanding ViewState

Monday, August 14, 2006 12:33 PM by InfinitiesLoop

Jouni --

I thought the humor would make it easier to read :) Can't please everyone I suppose. As for the paragraph lengths -- yes, I'm guilty of that. I do plan on revamping this article in the future and expanding on the examples at the end, so I appreciate the feedback.

OnInit -- actually there's no controversey really. In the Dropdown example not only did I suggest binding in OnInit, but I said to disable viewstate on the control. ViewState for child controls is indeed tracking in OnInit. It is not tracking for your OWN viewstate though. You can see it for yourself if you put a break point in OnInit and do a watch on something like:

this.ViewState.IsTrackingViewState // false

this.Controls[0].IsTrackingViewState // true

In the DateTime example I tried to initialize a label in OnInit, but _without_ disabling its viewstate. I hope that clears it up.

Thanks for the comment :)

# re: TRULY Understanding ViewState

Tuesday, August 15, 2006 3:17 AM by Jouni Heikniemi

All right, I accept that :-)

Re humor: I didn't have a problem reading your article, but writers of definitive tutorials ("TRULY understanding ViewState" sounds like one) should remember that non-native English speakers have considerably more trouble discerning the facts when entwined with witty remarks.

For this reason, I recommend either removing the humor or putting it in a sidebar (of course, not all jokes work that way). This way readers can easily identify it as optional content and focus their understanding on the factual parts. I'll say the same for most IT books as well - and it's not like I'm opposed to humor in general at all :-)

# re: TRULY Understanding ViewState

Tuesday, August 15, 2006 1:16 PM by InfinitiesLoop

Noted, killjoy!

http://dictionary.reference.com/browse/killjoy

j/k

Thanks for the feedback :)

# re: TRULY Understanding ViewState

Friday, August 18, 2006 5:26 AM by Calle Arnesten

In your text you say "Also for ASP.NET 2.0 developers, there's OnPreInit. That is actually a great place to initialize child control properties programmatically because it occurs before the child control's OnInit (and therefore before it is tracking ViewState) and after the controls are created. "

This is not working for me. If I override OnPreInit on a page the controls have not been created. They are all null.

Otherwise, thanks for a great article!

# re: TRULY Understanding ViewState

Friday, August 18, 2006 4:05 PM by InfinitiesLoop

Calle -- are you using a master page? Try calling base.OnPreInit, then check the controls, they should be there.

Thanks for reading :)

# re: TRULY Understanding ViewState

Monday, August 21, 2006 2:27 AM by Calle Arnesten

I tried without a master page and then it worked. Why will it not work with at master page?

# re: TRULY Understanding ViewState

Monday, August 21, 2006 11:59 AM by InfinitiesLoop

Master pages cause the controls to be shuffled around a bit during initialization. Did you try calling base.OnPreInit first?

# re: TRULY Understanding ViewState

Tuesday, August 22, 2006 6:47 AM by Calle Arnesten

Yes. Here is the code:

   protected override void OnPreInit(EventArgs e)

   {

       base.OnPreInit(e);

       Label1.Text = "Test"; // Crashes here with NullPointerException

   }

# re: TRULY Understanding ViewState

Wednesday, August 23, 2006 2:17 PM by GSR

Hi! I've read your article, very interesting, here is my problem: i have an user control, wich generates controls programmatically and initialize them in the Page_Load of the User Control. Now, when i try to generate the controls once again in the postback, the new values that i set are lost, the old values persist, the ones that i set first. The only way i found not to lost the new values, is creating the controls on the PreRender Event. What can i do?

Sorry for my english!!

# re: TRULY Understanding ViewState

Wednesday, August 23, 2006 2:59 PM by InfinitiesLoop

GSR -- Are the controls you are creating textboxes or other form controls (like dropdownlist)? You have to realize that these controls are designed to maintain the value entered by the user. The value you assign the control before you add it to the control collection is only meant to be a "starting" value. This can be illustrated if you declare a TextBox statically on the form and assign it a Text value. When the page first renders you see the value you gave it declaratively. But if you change the value as a user, then do a postback, your value remains, not the declared value. That is what it is _supposed_ to do. It sounds like you want to force the textbox value to your own value, potentially overwriting whatever the user entered, is that correct?

If thats the case, I highly recommend you change to creating the controls in OnInit. Then in Load you can assign the value you want, just as if it weren't a dynamic control at all. This works because by creating it in OnInit, you give the textbox the opportunity to load its posted value in the natural way (at the same time all the other controls do, before Load). When you don't create the control until Load, it misses that opportunity, and participates in the 2nd and last chance to load posted values which is after Load. Since its after Load its overwriting your assigned value.

In general its always better to separate the creation of a dynamic control and dynamic changes to it, ala OnInit and Load.

I hope that solves your problem... sounds like it should.

-Dave

# re: TRULY Understanding ViewState

Wednesday, August 23, 2006 3:01 PM by InfinitiesLoop

Calle -- I haven't had a chance to test this out. I know I've done it that way before, but perhaps there's something different about your master page setup that is yielding different behavior. May I ask why you need to initialize the control there? There's usually another/better way.

# re: TRULY Understanding ViewState

Thursday, August 24, 2006 7:41 AM by Paketim

Superb post. Thanks.

http://www.paketim.com

# re: TRULY Understanding ViewState

Thursday, August 24, 2006 9:51 AM by GSR

Thanks!! Problem solved. Your suppositions were right. I had three textboxes and I wanted to overwrite their values.

Very thankful by the received aid.

# re: TRULY Understanding ViewState

Monday, August 28, 2006 1:34 PM by Kalpesh

Can you please tell how to manage view state in callback events?

Because life cycle of the page is not same as PostBack!

# re: TRULY Understanding ViewState

Tuesday, August 29, 2006 4:04 PM by InfinitiesLoop

Kalpesh -- the life cycle is similar. It does get cut short because there's no point in PreRender or Render (there's nothing to render to). Viewstate and postback data are all still processed as normal though.

The one thing thats different about a callback is that the data which is posted is representative of the form at the time it was rendered on the browser. For example, if a textbox has value 'foo', the page will load with 'foo' in the box. If the user changes the value to 'bar', and then before doing another postback a callback occurs, the value posted in the callback data is 'foo'. There's a way to update the data so it represents the current state of the form instead if thats what you require. What issue are you having?

# re: TRULY Understanding ViewState

Thursday, August 31, 2006 2:51 PM by Steve

First I wanted to say thanks for a great article.  You did a great job of providing "Complete" information.  Unfortunately I think I read most of the uncomplete ones before I came across this article:-)

Second, I have an interesting problem that I'm hoping you can shed some light on.  I have a Page that implements the IPostBackEventHandler interface.  This is used to get a post back after performing a client side action (which is a popup).  The event handler receives information indicating if the popup was successful and there is information I would like to store in the viewstate at this point.  All seems well, however, there seems to be another postback or recursion of the page processing. Following is the sequence:

Page_Init(object sender, EventArgs e)

Page_Load(object sender, EventArgs e)

RaisePostBackEvent(string eventArgument)

***info saved in ViewState and correct***

Page_PreRender(object sender, EventArgs e)

Page_PreRenderComplete(object sender, EventArgs e)

----- now comes the unexpected -----

Page_Init(object sender, EventArgs e) *** data in ViewState reverted ***

Page_Load(object sender, EventArgs e)

Page_PreRender(object sender, EventArgs e)

Page_PreRenderComplete(object sender, EventArgs e)

I'm guessing, based on the info in your article that the viewstate was updated, but not re-written so when the next Page_Init comes in it loads based on the Request object hence losing the change just made.  That leads me to a couple of questions:

1.  Is my guess correct, or is there something I'm missing?

2.  What is a good way around this?  One thing I thought of was to override the viewstate and save serverside...one of the articles I read mentioned that...it would provide control over when the data is updated and ensure things aren't unexpectedly overwritten.

Thanks,

Steve

# re: TRULY Understanding ViewState

Thursday, August 31, 2006 3:06 PM by InfinitiesLoop

Steve,

Thanks for the comment. I think I need more context about your problem. You have a page that is opening an additional popup window (to another page I presume), and upon doing so it posts back? Maybe some code samples would make it more clear.

# re: TRULY Understanding ViewState

Thursday, August 31, 2006 3:54 PM by Steve

Sorry for the lack of details... I'm not sure which code samples might be beneficial so here goes.

A Main Page contains a variety of info and controls, one button is uxTestEmailButton which is an asp:button.  The following code is used to establish the PostBack & handle the popup...

       string emailInfoScript = string.Format("ShowEmailInfo()");

       string emailInfoUrl = Page.ClientScript.GetPostBackEventReference(this, "");

       uxTestEmailButton.OnClientClick = emailInfoUrl.Replace("''", emailInfoScript);

ShowEmailInfo is javascript which launches the popup window with the new page.  The popup page gathers User specific information to be included in the "TestEmail".  When a save / close button is selected on this popup, the ShowEmailInfo function captures the information and returns it.

The RaisePostBackEvent(string eventArgument) is received when ShowEmailInfo function returns and the eventArgument contans the return value from the ShowEmailInfo.

function ShowEmailInfo()

{

   var invokeString = '../Dialogs/EmailInfo.aspx';

   var returnValue = window.showModalDialog(invokeString, '', 'dialogHeight: 700px; dialogWidth: 800px; resizable: yes; scroll: yes; status: no;');

   if (returnValue == null)

   { returnValue = ''; }

   else

   { returnValue = 'EMAIL:' + returnValue; }

   return returnValue;

}

Sequence of events:

Main Page

Click TestEmail

ShowEmailInfo javascript function runs

Poup comes up

Fill in info in popup

click button on popup

popup closes

ShowEmailInfo javascript gets return info from popup

ShowEmailInfo javascript returns

Main page postback received

Hope this provides a bit more context.

Steve

# re: TRULY Understanding ViewState

Thursday, August 31, 2006 4:18 PM by InfinitiesLoop

Steve, I think you are getting two postbacks because of the way you are hooking up that click event. An ASP:Button does a postback naturally, because its a type="submit" button. But you've hooked up client script that runs when it is clicked, which also does a postback via the PostBackEventReference you are using. Hence, clicking the button causes two postbacks. I haven't tested it to see if thats the case (one would think the first postback would stop page processing, but I'm not sure if that's true).

Whenever you need a link or button that just runs script and nothing else consider using a non-webcontrol like an HtmlButton control, which don't cause postbacks naturally. Or, you can "cancel" the natural postback caused by clicking the button by returning false in the client click script.

In other words, go ahead and set the OnClientClick code, but be sure and end it with a "return false". Like this...

uxTestEmailButton.OnClientClick = emailInfoUrl.Replace("''", emailInfoScript) + ";return false;";

If that's the problem then great. But it goes to show what a scapegoat viewstate has become... everyone assumes their problem is a viewstate issue. I assure you, viewstate works perfectly. :)

If that doesn't help then we're figure it out... but it still won't be a viewstate problem. Let me know ;)

# re: TRULY Understanding ViewState

Thursday, August 31, 2006 5:12 PM by Steve

That resolved my issue.  It makes perfect sense, but then again hindsight is 20/20.

Thanks again, the article really helped and even more so for the latest thought.

Steve

# re: TRULY Understanding ViewState

Friday, September 01, 2006 3:44 AM by Gupta

Simply Awesome. Thanks for taking time to post this information.

# re: TRULY Understanding ViewState

Friday, September 01, 2006 10:46 PM by Martin

Wow! You saved my life.

Well... almost! :-)

# re: TRULY Understanding ViewState

Friday, September 01, 2006 11:06 PM by InfinitiesLoop

Wow... I haven't heard that one before. :)

Why only almost? :(

# re: TRULY Understanding ViewState

Tuesday, September 05, 2006 3:53 AM by bb

Great article!! I just wantet to say keep the humor! It did make the article it easier to read, and it also "stimulates" the brain in a different way, making it easier to remember the material. This princible is used in the "Head First" book series. Great books, unfortantly Java based :(

I don't believe many non-native English have a problem with your humor (I'm a non-native English), because you need to have a certain English skill to even try to read articles like these.

# ViewState, a fairy tale?

Monday, September 11, 2006 7:59 AM by bojanv

Since, ViewState is a important part of developing web pages (specially web controls), i wanted to know,

# re: TRULY Understanding ViewState

Monday, September 11, 2006 5:49 PM by Pierre

Thank you for this great article.

I have  viewstate question:

I am right to think that viewstates of disabled controls are not serialized ?

I have a Page that implements the IPostBackEventHandler interface.  

When the user clicks a button, a javascript function is called. This function calls GetCallbackResult() that fetches data in a database based on the value of a textbox. In the callback function, I populate a list with the result.

Because I don't want the user to enter new data in the textbox before the result of the request, I disable it in the Javascript function and I enable it in the callback function.

I noticed that viewstates (in fact control states) are not posted to the server when the control is disabled so I don't have the value of the textbox in GetCallbackResult().

Thanks.

By the way, I solved my problem by passing the value of the textbox in parameter (RaiseCallbackEvent()).

# re: TRULY Understanding ViewState

Monday, September 11, 2006 7:03 PM by InfinitiesLoop

Pierre --

ViewState is maintained (and serialized if there is any 'drity' data) so long as EnableViewState is true and ViewState is not disabled for any of its parent controls.

I think you really had double trouble with what you had -- first of all, by themselves, callbacks do not post the values of all the controls on the page at the time the callback is made. Instead, they post the values of all the controls as they were at the time the page was rendered. So if a TB has value "a" when the page renders, then the user changes it to "b", and then a callback occurs -- the server side will still see the value as "a". The 2nd part of the problem is that even if it did update the data that is posted, since you were marking it as disabled, it wouldn't have sent the data _at all_.

There is a way to reinitialize the callback data so that posted values are up to date with the latest changes by the user. However, your solution of passing the textbox value as a parameter to the callback is a much better solution if you ask me. I'd stick with that. I decouples your callback handling logics from the rest of the page.

If you really want to ensure the latest data is posted, calling the JS function WebForm_InitCallback() will do that for you. If you call that and then disable the TextBox, I bet it will work. I'd recommend sticking with the parameter solution though :)

# re: TRULY Understanding ViewState

Wednesday, September 13, 2006 7:00 AM by Potiguar

Many thanks for writing the best ASP.NET article ever! I always come back to this post for guidance when developing my controls & pages.

# re: TRULY Understanding ViewState

Thursday, September 14, 2006 2:05 AM by Lord Fetta Cheesabio IV of Denver

Neat article, I wouldnt worry too much about the comments about humour, I think it helps. I guess you could split the article into two columns to make the humour optional, something like "Click Here if you're feeling grumpy".

I'm having a bit of an odd situation with viewstate and would appreciate any feedback from anyone else reading this. Im generating dynamic controls with a method that gets the list of controls to generate from a database, something like this:

makeTheLists()

{

 //all the calls here are loaded dynamically from the DB, there isnt

 // actually two seperate lines of hardcoded calls to cretae the lists

 createAndloadCountriesList();

 createAndloadStatesList( getCountryListsSelectedValue()  );

}

now i've added an autopostback value to the country drop down list but the problem is that the state list is populated and created right after the country list was created and it needs the selected value of the country id. If I call 'makeTheLists' from my pages Init() method I can correctly output the selected value of the dynamically created country list in my PageLoad for example,  and the correct country is selected when the screen refreshes BUT when the state list is being populated it is COMPLETELY unaware of the selected country value !!!!

# re: TRULY Understanding ViewState

Thursday, September 14, 2006 3:10 AM by InfinitiesLoop

Dear Lord Fetta Cheesabio IV of Denver,

Generally its best to separate the creation of controls from the injection of dynamic data into them. You can't do both at the same time because when you are creating controls, they nor any of the other controls on the page have been updated with the dynamic state of the page. So in other words, _dont_ depend on the country SelectedValue during the creation of the State list.

The pattern you want to follow is to (1) create the controls as early as you can (OnInit is a good start) and then (2) separately, load/populate/initialize/whateveryoucallit as early as you can. In your case the earliest you can create the controls is OnInit -- but you can't populate the state list yet since the country list hasn't been updated with its posted/selected value. That happens by OnLoad, so that is where you must populate the state list, using the selected value. But you must take care to only do this initialization when the country value changes (if you rebind it every time you'll revert its selected value to the first item). Since the list will use viewstate to remember the items that were databound to it, all is well. But going on --- if you are populating the list manually before adding it to the control collection, or if you have disabled viewstate on it, then it wont rembmer them all you'll be forced to populate it all the time. To avoid the problem of overwriting the posted/selected value in this case, avoid creating it until OnLoad as well. By delaying its creation you stall it from loading the posted value until after OnLoad. And finally -- the next problem you'd have is that in this case, after switching countries, the list will attempt to load a posted value which doesnt exist in the list and so will throw an exception. To avoid that, you give the list an ID that is based on the country list's selected value. That way when the country changes, the new state list has a new identity and won't try to load the previous lists' posted value.

Whew... I kind of rambled there but I hope it sheds some light on your situation. You picked a sort of complex scenario to have a problem with.

The real underlying problem if you ask me is that you are creating the controls dynamically. If you make them static again via a Repeater, all the issues I just rambled on about go away. Doing things dynamically when there's a static way to do it just makes things more complex than they need to be.

...And its problems like these that have motivated me to write the articles I'm working on about dynamic controls. If you have a problem like this or any problem with Dynamic Controls (even if you think the problem is with ViewState), please read them.

# re: TRULY Understanding ViewState

Thursday, September 14, 2006 10:28 PM by Enlightened Lord Fetta Cheesabio IV of Denver

thanks for the comments... I ended up splitting the code a bit as you suggested and calling them manually from Page Load and oninit which made things easier to handle. The extremely flexible functionality I needed meant that I had to use dynamic controls (unless there's something about Repeaters I dont know).

---------------

"Let not man glory in this that he loveth his country, let him rather glory in this that he loveth his kind." - Baha'u'llah

---------------

# ASP.NET ViewState Details

Wednesday, September 20, 2006 8:06 AM by Richard's Ramblings

The following link was mentioned by Manoj Nagpal on the Aus-DotNet mailing list this afternoon. It's a must read for all ASP.NET developers. It's a very enlightening article on ViewState. http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx

# re: TRULY Understanding ViewState

Thursday, September 21, 2006 6:47 PM by Rahul Patel

In solution #2 for problem #4 you give the following code:

public class DateTimeLabel : Label

{    

 public DateTimeLabel()

 {        

   this.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");    

 }

}

Could this also be done like this?

public class DateTimeLabel : Label

{    

 protected override void OnInit(EventArgs e)

 {        

   this.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");  

   base.OnInit(e);

 }

}

Would overriding the OnInit method work?

# re: TRULY Understanding ViewState

Thursday, September 21, 2006 9:01 PM by InfinitiesLoop

Rahul -- you could do that, and it would work fine. But you'd be overwriting any text value that a user of your control provides declaratively, because declared attributes are assigned before OnInit. Doing it in the constructor is a way of providing a default value that can be overwriten by any of the usual means.

# re: TRULY Understanding ViewState

Wednesday, September 27, 2006 4:13 PM by TBD

Great article!

I have a question though.

I'm using ASP.NET 1.1. I have a login.aspx site that contains two textboxes and one button; tbUsername, tbPassword and bLogin. When pressing the bLogin button it logs in with an API library (which keep me logged in until i logout manually). The problem here is that later when I trace the target page (default.aspx), immediately after logging in (login.aspx), I can see tbUsername, tbPassword, bLogin as well as their values in clear text! I want to remove these values or putting them into the encoded viewstate (to prevent password from being visible). Since I'm using an API that keeps me logged in, the values don't need to be posted.

How can I do this?

Thanks in advance.

# re: TRULY Understanding ViewState

Wednesday, September 27, 2006 7:56 PM by InfinitiesLoop

TBD -- I'm not sure what you mean you can see the values in clear text. You said you are on an entirely different page. How are you transferring from login.aspx to default.aspx? Is it a Response.Redirect or Transfer? If it's a transfer, the target page can access the posted values from the previous page, because its all done within one request. If you don't like that, do a redirect instead. It's got nothing to do with ViewState, unless I'm not understanding your problem. Let me know.

# re: TRULY Understanding ViewState

Thursday, September 28, 2006 11:57 AM by Mark Olszowka

Maybe just slightly off topic but....

Any thoughts/comments on use of a "custom" or "personal" statebag.

There have been many times that I wanted to store one or more custom values in "viewstate" but did not want to turn viewstate on.  

I realize you can store these values in hidden form fields, but it would be nice if you dealt with this custom data the same way as if you were placing it in the page's builtin viewstate, ie serialization, encryption, tamperproof, etc.

I tend to keep viewstate turned OFF unless it is absolutely necessary (and with the new ControlState, that is almost never the case.

I see that the statebag object in flagged as Not Inheritable.

# re: TRULY Understanding ViewState

Thursday, September 28, 2006 4:29 PM by kmobarra

Thank you for the great article. It filled a big gap...

I have a problem that sounds similar to one discussed in the comments, but it's a bit different and I still can't figure an easy way to tackle it.

I have a wizard-like part in my application. Each "page" is actually a user control that is loaded dynamically, depending on what the user wants to accomplish. While these user controls may be loaded and unloaded with each postback of the page, they not only have to persist their own data across postbacks, but also alter a data structure that is basically the big picture that they all are building (currently stored in an xml-driven object). Now the problem is two-fold:

1- How exactly can I reload the right control on each postback, with its latest state?

2- How should I store the "big picture" structure, so they all can access and alter it?

Any thoughts are appreciated.

# re: TRULY Understanding ViewState

Thursday, September 28, 2006 6:12 PM by InfinitiesLoop

Mark -- Even if you could inherit from StateBag, I don't think it would help.

There's a couple of ways you could do it... one, you could NOT turn off viewstate. Instead, wrap all your controls in a PlaceHolder which does have viewstate disabled. Then you can just use the page's viewstate (or the user controls, whichever you are) to store stuff in ViewState, but still have viewstate essentially disabled on all the controls on the page or control (disabling viewstate on a control disables it for all its children too).

Another way is you could use ControlState. You'd have to write a custom control to let you do it though. It would be like a ControlStateHelper control, could be useful for other purposes. Not trivial to write though.

It's good that you turn off ViewState by default, but I actually wouldn't recommend that practice, at least not if its only because you want to avoid the fluff. A well written, correctly written page will only use viewstate when it really needs to, even if its enabled. So turning it off just allows you to be "lazy" and do things that wouldn't be good if it were on. You're letting your ViewState muscles get atrophy :(

# re: TRULY Understanding ViewState

Thursday, September 28, 2006 6:17 PM by InfinitiesLoop

kmobarra -- Just keep in mind you must load the user control on every request. If you load the "next" user control when the user clicks "next", thats fine. But then on the next postback the control is gone and won't process the results, unless you load it again. To do that you can just remember which step you are in within this wizzard, and make sure you load the appropriate user control. So imagine you are on step 1, and Step1.ascx is loaded. The user clicks 'next'. In OnLoad or LoadViewState, you realize you're on step 1 still, so you load Step1.ascx again. Then the next_click event fires. You remove Step1.ascx from the page (you probably put it into a placeholder), then load Step2.ascx, and update the step # you are on. The next postback that occurs, Step2.ascx will load instead.

If you follow this pattern the controls will maintain their state automatically. There's no magic to be done.

As for them sharing the "big picture"... the driver of this page, whatever it is that is loading the controls, can provide to them via a property or method the data structure. It could do this after ever time it loads them dynamically. That way the controls will always be given to them the structure they need. Between postbacks of course, you'll have to have a way to save this structure. How best to do that depends on the nature of the document -- if its compact enough, and easy enough to covert to xml, you could convert it to an xml string and store it in ViewState. Or if you have some way of saving it to a database, you could do that too.

I hope this helps... good luck.

# ASP.NET 2.0 Master page and child pages viewstate inheritance

Friday, September 29, 2006 12:03 PM by I want some Moore!

ASP.NET 2.0 Master page and child pages viewstate inheritance

# re: TRULY Understanding ViewState

Monday, October 09, 2006 2:48 AM by RussianGeek

THANK YOU VERY VERY MUCH!!!

The best article about ViewState I have ever read...

# re: TRULY Understanding ViewState

Tuesday, October 10, 2006 4:23 PM by Big Red

I am having problems with a bulk delete I have in a gridview.

The gridview is nested within a repeater.  The gridview has a checkbox for each row and a single 'Delete' button.  When this button is pressed, it goes to its onclick function where it looks for checked boxes, and initializes a delete.

This all seems to work fine and dandy, except when two users are working simultaneosly.  If user a deletes rows 1,2 and 3, and user B adds 5 rows at the same time, none of the rows are deleted, and the checkboxes continue to be checked.  (Although, if one of the 5 rows is inserted and displays between 1 and 2 or 2 and 3, the first 3 rows are checked.)  

I can't seem to figure out how to delete these rows before ASP.NET checks to see if the gridview has changed.

Any help would be greatly appreciated.

# re: TRULY Understanding ViewState

Tuesday, October 10, 2006 4:24 PM by Big Red

This was a very informing article.

# re: TRULY Understanding ViewState

Tuesday, October 17, 2006 6:51 AM by Matt

Excellent article thanks. Here's a question though: an alternative to having properties that are directly put into/obtained from ViewState (in get() and set()) is to store the property to a private member variable and explicitly save to/obtain from ViewState in the SaveViewState() and LoadViewState() methods.

What are the pros and cons of this?

# re: TRULY Understanding ViewState

Tuesday, October 17, 2006 11:35 AM by InfinitiesLoop

Matt -- that works fine, but you have to be careful not to stuff the default value into viewstate when saving -- and, you have to be careful not to overwrite the existing value during load if viewstate for that value is empty. Much easier just to use the statebag directly.

Basically, just loading your control or page for the first time (!IsPostBack) shouldn't result in any persisted viewstate at all, unless your control or page has loaded dynamic data and plans on letting viewstate maintain it.

# re: TRULY Understanding ViewState

Monday, October 23, 2006 2:09 PM by John

Great article.  I've read it a few times in an attempt to hammer these questions into my head.  Although sometimes I would like to hammer asp.net

I've run into a strange problem when I create checkboxes dynamically.  The checked state of the checkboxes seem to be reloaded fine on the page, but not until after Page_LoadComplete.  The checked state always seem to evaluate as false before Page_LoadComplete.  Any insight into would be appreciated!

# re: TRULY Understanding ViewState

Monday, October 23, 2006 4:28 PM by InfinitiesLoop

John -- are you creating them during the OnLoad phase? If so, thats why. Posted data is processed in two passes -- one before OnLoad, and one after OnLoad. The one after OnLoad is so that controls that are dynamically loaded in OnLoad can still load their posted data. However, that also means their state won't be up to date until the 2nd pass, so basically in your PreRender phase.

If you can rework your solution so they are dynamically created during OnInit it will solve your problem since they will load their state before OnLoad. If OnInit is too early because you depend on form state, you could do it in LoadViewState -- which is just before form data is processed.

# re: TRULY Understanding ViewState

Thursday, October 26, 2006 6:10 PM by Bryan

I have a question regarding dynamic "Web User Controls" that contain Databound DropDownLists.

I have one UserControl being loaded dynamically depending on the number of times the user has pressed a button (could add infinite user controls to the page).  Now, the above "user control" calls a second "user control" and loads it into a PlaceHolder on the first "user control" depending on the dropdownlist within the first user control.  This can happen infinite number of times for each "1st User Control" on the page.  The "second user control" has databound DropDownlists in it.  

Now, I have the enableviewstate for all of these controls set to "True".  I know, I know... bad me.  But the funny thing is, the "1st user control" keeps its state.  The "second user control" does not keep its state on postback, even though viewing the page trace, the viewstate for that particular dropdown control is the correct selectedvalue (it resets itself).

# re: TRULY Understanding ViewState

Friday, October 27, 2006 11:37 AM by InfinitiesLoop

Bryan -- I'm not 100% sure I understand the scenario. But it sounds like you must have some way of tracking which controls have been created. Remember that when you add a control dynamically, that control will vanish from the page on the next postback unless you add it back again. So you need to keep track of which selected values the user has clicked on, and then rebuild the list of user controls on postbacks.

# re: TRULY Understanding ViewState

Friday, October 27, 2006 12:14 PM by Bryan

I'm having trouble trying to "track" the controls state.  I'm kinda a newb at this type of stuff, and I get confused when something isn't quite straight forward.  I do end up re-adding all of the dynamic controls to the page.

Here is a piece of code that I have the can iterate through all of my controls that have been added to the page (to tell me what I'm seeing).  Maybe I could use something like this to help me track the control value's?

   Protected Sub ParseControls(ByVal c As Control)

       For Each child As Control In c.Controls

           If InStr(child.ClientID, "DropDownList", CompareMethod.Text) > 0 Then

               Dim RuleDropDownList As New DropDownList

               RuleDropDownList = child

               Response.Write(child.ClientID & " " & RuleDropDownList.SelectedValue & "<br>")

           End If

           ParseControls(child)

       Next

   End Sub

Maybe it would help you understand my situation if I sent you some examples of what I'm trying to do?

I appreciate any feedback you may have!

# re: TRULY Understanding ViewState

Saturday, October 28, 2006 4:49 AM by InfinitiesLoop

Bryan,

So you are navigating through the controls in order to detect dropdown lists, and then writing out their selected value.

I don't know what problem you are specifically having, but I'll try to help as best I can if you give me more details. Start by sending me mail about the high level goals you have. Its likely you can avoid using dynamic controls altogether, and that greatly simplifies things. Honestly though I'm quite busy lately so I can't promise a speedy response :)

# re: TRULY Understanding ViewState

Sunday, October 29, 2006 3:10 AM by Cat

Great article! Before I read this article, I was confused by why the value of IsDirty property is always true, and only in a few situation it's set to be false by SetItemDirty method.

When deriving from an existing control, you can set any property at any time without it being saved to __VIEWSTATE, as long as you know which StateItem it uses and remember to reset its IsDirty property to false. Here's a new DateTimeLabel with its Text property set in OnLoad:

public class DateTimeLabel : Label {

   protected override void OnLoad(EventArgs e) {

       this.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");

       this.ViewState.SetItemDirty("Text", false);

       base.OnLoad(e);

   }

}

# re: TRULY Understanding ViewState

Sunday, October 29, 2006 2:35 PM by InfinitiesLoop

Cat -- SetItemDirty is a trick you can use if you must, but in general I wouldn't recommend it. This DateTimeLabel doesn't behave like most controls, and that inconsistency is going to be frustrating for those who use it. Maybe in this situation it would be alright, since it isn't likely a dev would want to set the text property (since its specifically designed to show the date). But if they did, you'd be overwriting the value with your own.

# re: TRULY Understanding ViewState

Sunday, October 29, 2006 9:09 PM by Jack

First, thanks for the great article. Next, a quick question.

On August 29th, you state:

"For example, if a textbox has value 'foo', the page will load with 'foo' in the box. If the user changes the value to 'bar', and then before doing another postback a callback occurs, the value posted in the callback data is 'foo'. There's a way to update the data so it represents the current state of the form instead."

What is that way to get the latest values when you make a callback instead of postback?

Thanks.

# re: TRULY Understanding ViewState

Monday, October 30, 2006 2:59 PM by InfinitiesLoop

Jack --

Normally you perform a callback like this:

WebForm_DoCallback(...);

To 'update' the form data that is posted so it is up to the minute, you must do this just prior:

__theFormPostData = "";

__theFormPostCollection = [];

WebForm_InitCallback();

# re: TRULY Understanding ViewState

Tuesday, October 31, 2006 2:10 PM by Nash

I’m posting to discuss an interesting symptom of ViewState. I've read your article, which is very informative, but I am still not quite certain as to which characteristic is causing the aforementioned symptom. In any case I think you may find interest in this.

In a nutshell the symptom is simply that an arraylist is inserted into the ViewState upon a textbox change event, and after a certain sequence, it will not be persisted in a secondary event of a button click.  Previous ViewState entries are persisted, but the latest entry is missing.

Here is the description:

The page setup consists of three simple dynamic text boxes populated by database. When the user changes the text values each is saved to ViewState until the user is ready to save changes to the database. The error arises from an interaction between the postback of the textbox change and the postback of the button click that is used to save the data (SaveButton).

For example, if a user enters values into each three text boxes {“A”,”B”,”C”], each is posted back in turn as the next textbox is selected. But, upon the last entry of “C” when the SaveButton is clicked before anything else, the ViewState symptom may occur, based on the event firing.

The result is that both text change and button click events do fire in order. The text change correctly updates the ViewState with “C”, but stepping through the SaveButton the ViewState contains all inserts accept those from the “C” text change event.

Here is the interesting difference. Perhaps, you understand why it is causing the disjunct ViewState symptom. Upon the down click of the SaveButton a wired javascript function pops up and allows the user a typical “Are you sure you want to save” message.

Sometimes this action only calls the waiting onchange event; which causes a refresh and works. Sometimes this action calls both the onchange event and the button click event; which causes the symptom. When the latter happens, the wired javascript handler displays the yes/no alert, the text change fires and populates the correct values into ViewState, but as the user selects ‘yes’ and the button click event is run…the ViewState is still antiquated. That is to say, ViewState hasn't been updated with the most recent addition of "C" in the fired text change event.

The work around is easy but I am not sure why this is the case. I would be interested if you know the intricacies of why this occurs.

Apologies for any specifics & Regards,

Nash

# re: TRULY Understanding ViewState

Wednesday, November 01, 2006 7:06 PM by InfinitiesLoop

Nash --

Why are you storing data in response to TextChanged? Why not just calculate your data when you need it, such as in the button click event? That way it doesn't need to be in viewstate at all, and you don't need postbacks between each textbox.

Assuming you can't change that design... something else you said concerns me. You have a button that opens a javascript confirm dialog. You seem to be saying that there is a postback occurring _while_ this dialog is open? I'm kind of lost after that -- the dialog is a client-side operation, there shouldn't be anything at all going on server side at that point, not until they user dismisses the dialog.

Just a shot the dark here, but since you are doing postbacks between each textbox, its quite possible the user is clicking on the button before the last postback is finished. So you'd see the postback of 'C' occuring correctly, but then another postback would come in afterwards, and that postback would not contain the updated viewstate since it was posted from the same form the first one was. If you get rid of the postbacks like I stated in the first paragraph, your form will be much zippier and won't have this problem. Otherwise, you'll have to disable the submit buttons when the postback starts, or the user may click them too quickly.

# re: TRULY Understanding ViewState

Thursday, November 09, 2006 5:09 PM by kmobarra

I have a bit of a catch 22 here that I hope you (as the only person I know that understands ViewState :) can help me with: I have created a tree usercontrol that is populated dynamically, after its container control sets its data source. Note that the control is not loaded dynamically by the container, but just populated. If I could populate the usercontrol in its page_init event, the controls would get properly registered with the container page's viewstate and when a postback happened, the control would get populated in init, before the container page started to assign viewstate and by the time the control's Page_load would fire, I had access to the controls' last state before postback. The problem is that again, the usercontrol's datasource is determined in the container page and therefore it's not available at the time page_init happens, but later in Page_Load, which is too late. Can you suggest a way out of this dilemma? Thanks, Kathy

# re: TRULY Understanding ViewState

Thursday, November 09, 2006 9:03 PM by InfinitiesLoop

Kmobarra --

It shouldn't have to matter when you populate the control -- before, or after viewstate is loaded. The fact it does matter kind of indicates a design issue. Instead of populating as soon as the datasource is assigned, why not populate in DataBind() just like other databound controls do? The containing page would set the datasource then call databind -- but it would only do this on !IsPostback. Then in your tree control, you have to rebuild the control tree on LoadViewState. So you will need to save whatever information you need into ViewState at the time DataBind is called to be able to do that.

That being said, let me make sure I understand the problem. The page is assigning the datasource during page_load, and I presume it is doing that on every request? So your problem is, the page loads with the first set of data -- then the user makes some client side changes and performs a postback. The controls viewstate is loaded and it repopulates itself. Then page_load comes along again and the data is reassigned, causing the control to be repopulated and the values changed by the user are lost. Am I right? Or, perhaps the issue is that the posted values of input controls like textboxes are not updated by page_load (because the controls were added during page_load, they won't get posted values until the 2nd pass a loadpostdata which is after page_load)?

I still think that rethinking the design a bit like I said in the first paragraph is the right way to go... but a quick workaround for the situation I described is for the page itself to dynamically load the control. This is assuming your issues is with viewstate... it won't help you with the post data. In page_load, you create the control, assign the datasource, and then add it to the control collection (add it to a placeholder more than likely). This lets the page get a chance to assign data to the control before its Init event, since Init won't happen in the control until it is added to the control tree. It's a hack solution though... your control aught to behave like every other databound control. The page that uses it should be able to decide when the data is refreshed and how often.

# re: TRULY Understanding ViewState

Thursday, November 09, 2006 9:11 PM by InfinitiesLoop

To Everyone -- pretty much 100% of the questions I get about ViewState issues aren't really ViewState problems at all. It usually boils down to a dynamic control issue.

Just keep this in mind -- if you add a control to the tree dynamically, you must add that control again on the next request, it wont be there automatically. ViewState is responsible for the data in the control, not the existence of the control in the first place.

But don't confuse that with initializing the control. When you add a control dynamically you should initialize its "initial" values before adding it to the control tree. But the values you give it SHOULD NOT be dynamic! For example... theres a dynamically added label on your page that starts off saying "ABC". A button on the page changes its text to "XYZ" in the click handler. When you initialize the label just before adding it to the tree, you should always set its text to "ABC"! The fact the text was changed is being maintained in the label's internal ViewState -- no reason for you to try and remember it yourself. Rest assured, the label will say "XYZ" if that button was clicked during a previous postback.

# re: TRULY Understanding ViewState

Friday, November 10, 2006 8:27 AM by kmobarra

I take your advice and change the design of the tree control. Thank you. Kathy

# re: TRULY Understanding ViewState

Tuesday, November 21, 2006 2:23 AM by Ruben Cordoba

Because disabling viewstate on a control disables it for all its children too, I have changed the property EnableViewState from False to True on the GridView on page Animal.aspx. However the dynamic user child control AnimalPictures.ascx doesn't persist the viewstate neither. An so, the DataList1_ItemCommand is still not fired.

# re: TRULY Understanding ViewState

Tuesday, November 21, 2006 4:41 AM by InfinitiesLoop

Ruben -- it sounds like theres more going on than you describe. Is the AnimalPictures.ascx the control that contains the Grid View or the other way around? Are you saying viewstate is disabled on the usercontrol as well? You don't necessarily need viewstate enabled to do what you need to do -- itemcommand really has nothing to do with viewstate. Can you provide more details or code samples?

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 2:23 AM by Ruben Cordoba

InfinitiesLoop -- You can find details and code samples about what I am talking on a previous comment in this blog on Saturday, November 11, 2006 5:35 PM by Ruben

By the way, you said that ItemCommand really has nothing to do with viewstate. I don't think so. I feel that viewstate is the cause of the problem and ItemCommand is not fired because viewstate is not persisted on the dynamic user control called AnimalPictures.ascx.

I have tried different combinations turning on and off viewstate on the GridView and the dynamic user child control. Neither of them work propertly. Let me know your opinion and suggestions.

Thanks

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 1:37 PM by InfinitiesLoop

Ruben -- you were correct that turning on ViewState for the GridView, because it applies to all children.

But now that you are utilizing ViewState on the GridView you should not databind it every request. What is happening is the controls are being recreated (automatically for you) when ViewState is loaded, but then you DataBind again, which recreates them all -- and the newly created controls have a different identity (autogenerated ids), so the 'button' you click on isnt the same button.

Put a !IsPostBack around the databind call, just like you have in the user control, and I don't see why it shouldn't work.

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 2:34 PM by Ruben Cordoba

Putting a !IsPostBack around the databind call on Animal.aspx.vb doesn’t work. The reason is the following:

If I use !IsPostBack around the GridView databind call, when the page is posted back, the GridView is persisted thanks to the viewstate is loaded. Until here, everything works property. However, because the GridView is not being re-created (automatically for me) the GridView1_RowDataBound is not fired, and so, I don’t have the opportunity to re-create the dynamic user child control called AnimalPicture.asc when the GridView is populating the first row. Because the dynamic user control is not re-created after postback, the Page_Load event handler on AnimalPictures.ascx.vb is not fired neither. And so, the  DataList1_ItemCommand is still not fired.

If you have another idea, I am ready to test it.

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 2:50 PM by InfinitiesLoop

ItemCreated is called every request regardless of whether it is being databound or not. That is the correct place to do things like what you are doing.

Curious -- why not simply declare the user control in the template rather than load it dynamically? Then you wouldn't even need this event. You could even set that HiddenField property on it using the proper Databinding syntax HiddenField='<%# Eval("AnimalID") %>'

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 3:07 PM by Ruben Cordoba

You said: why not simply declare the user control in the template rather than load it dynamically?

I don't understand what you mean. Can you explain to me your idea with more details, please?

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 3:15 PM by Ruben Cordoba

The reason to load the user control dynamically is because I need it only for the first populated row populated on the GridView. If I declare the user control in the template, I think, it is not very efficient to have a user control on each GridViewRow when it is only used once.

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 5:11 PM by Ruben Cordoba

Infinities Loop -- As you suggested me, instead of using GridView_RowDataBound as the place to re-created the dynamic user control, I have used GridView_RowCreated this time. Debugging the code, I can see that when clicking on the LinkButton, the dynamic user control is re-created within the GridView_RowCreated property after postback, and also, the Page_Load event handler on AnimalPictures.ascx.vb is fired. However, the  DataList1_ItemCommand is still not fired. I cannot understand why.

The GridView is using EnabledViewstate = True and I am putting a !IsPostBack around the databind call on Animal.aspx.vb. What wrong is happening?

# re: TRULY Understanding ViewState

Wednesday, November 22, 2006 7:04 PM by InfinitiesLoop

Ruben -- the user control contains a DataList. I assume the button you are clicking is inside the datalist, no? The DataList will "consume" the click event and fire its own item command event -- and then thats where it stops. If you want it to keep on bubbling up you will have to add code to handle the DataList item command and then raise a Bubble event. Then the GridView will get the Bubble event and raise its ItemCommand.

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 2:41 AM by Ruben Cordoba

Infinities loop -- Let me recap several things:

I have created a label control for testing purposes inside the dynamic user control. I have assigned the value “Hello world” to the label control declaratively. After that, at the end of the Page_Load event handler I have changed the text property value to “Happy programming” programmatically to start tracking viewstate. When the page is posted back and the execution code is located at the beginning of the Page_Load event handler, I see that the text property value of the label control is “Happy programming”. That means:

1. Using GridView_RowCreated as the place to load the dynamic user control and putting a !IsPostBack around the databind call on Animal.aspx.vb has been an improvement in the system. Now the viewstate is persisted inside the dynamic user control. Before, it wasn’t.

2. You were correct and I was wrong. ItemCommand really has nothing to do with viewstate. ItemCommand is still not fired and viewstate is persisted inside the dynamic user control.

Answering your previous question: Yes, the user control contains a DataList and the LinkButton I am clicking is inside the DataList. You can look at the code I provided to realize about it.

What is happening now is the following:

When I click the LinkButton and the page is posted back, the Page_Load event handler inside the dynamic user control is fired. However, when the Page_Load event handler has finished to be executed, the execution code jumps to the detail page about the animal picture clicked on, and the DataList doesn’t have the opportunity to "consume" the click event and fire its own item command event. Because of that, the DataList_ItemCommand is not fired inside the dynamic user control and I cannot raise a Bubble event. So, the GridView will not get the Bubble event and raise its ItemCommand.

Why the DataList_ItemCommand is not executed after finishing Page_Load? I don't know.

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 10:07 AM by Ruben Cordoba

Only removing the line !IsPostBack around the databind call on the dynamic user control I can do the DataList1_ItemCommand to be fired. The problem is that I need that line and it shouldn’t be removed.

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 1:34 PM by InfinitiesLoop

Ruben -- Do you still have ViewState enabled on the GridView? If its enabled you should be able to keep !IsPostBack.

I notice you are using an image inside a linkbutton. Why not just use an ImageButton? It gives you the functionality you want, you can still set a command name and argument, etc.

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 3:25 PM by Ruben Cordoba

InfinitiesLoop - I have viewstate enabled on the GridView and dynamic user control. Also, I have !IsPostBack around the databind call on the GridView and dynamic user control. The dynamic user control is re-created inside the GridView_RowCreated.

Yes, you are right. I will change the implementation to use ImageButton instead of an image inside a linkbutton.

Anyway, I don't know what to do more to fire the DataList1_ItemCommand.

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 4:16 PM by Ruben Cordoba

I have changed the LinkButton for an ImageButton as follows.

<asp:ImageButton ID="ImageButton1" runat="server"  CommandName="ImageButton1" CommandArgument='<%#Eval("PictureID") %>' PostBackUrl="~/PictureDetails.aspx" OnCommand="ImageButton1_Command" />

Once the ImageButton1 is clicked on, what is supposed to be fired first, ImageButton1_Command or DataList1_ItemCommand? Neither of them is fired.

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 5:38 PM by InfinitiesLoop

The CLICK (not COMMAND) event should fire on the image button. If it isn't that explains why item command isn't. Does the button still exist after the postback? Are you doing anything else peculiar besides what you've outlined?

Check this... in the page put a break point in OnLoad, PreRender and in the GridView_ItemCreated event. On the postback where you click on the image button, what happens first, ItemCreated or PreRender?

# re: TRULY Understanding ViewState

Thursday, November 23, 2006 6:21 PM by Ruben Cordoba

Before posting back the page, the order the events are executed is:

Page_Load

GridView1_RowCreated

Page_PreRender

After posting back the page, the order is:

GridView1_RowCreated

Page_Load

Page_PreRender (is not fired)

ImageButton1_Click (is not fired)

The ImageButton still exists after the post back:

DataList1.Controls.Count -> 4

DataList1.Controls(0).ID -> Nothing

DataList1.Controls.Controls(0).ID -> Nothing

DataList1.Controls.Controls(1).ID -> ImageButton1

# re: TRULY Understanding ViewState

Friday, November 24, 2006 12:43 AM by InfinitiesLoop

There's no way Page Prerender doesn't fire unless there's a redirect occuring or its a callback or atlas partial update. There must be more going on than you've described. Do you want to send me your project? I may not be able to run it without your middle tier or backends but I can still tell a lot more.

# re: TRULY Understanding ViewState

Saturday, November 25, 2006 1:41 AM by Ruben Cordoba

InfinitiesLoop -- There are several points I would like to comment to you:

1. After clicking on the ImageButton and the page posting back, why GridView1_RowCreated is executed before Page_Load? Is that the normal flow? I think Page_Load should be always be executed before GridView1_RowCreated. Am I correct?

2. Why Page_PreRender is so important for you to determine if things go good or wrong? I never use Page_PreRender in my project.

Thanks

# re: TRULY Understanding ViewState

Saturday, November 25, 2006 2:14 AM by InfinitiesLoop

Ruben -- (1) No... RowCreated will happen whenever the rows are recreated. That isnt necessarily at a particular point in the lifecycle. It so happens that the rows are recreated immediately after viewstate is loaded, which is before page load. (2) I was only using PreRender as a measure of when the event fires -- certain things are too late if they happen after prerender. No reason to get into the details. You should definitely always get a page_prerender event though, unless again, the postback is a partial update in atlas, a callback, or a redirect or response.end occurs before hand.

# re: TRULY Understanding ViewState

Tuesday, November 28, 2006 2:23 PM by John

Great read! Clearly explained.

# re: TRULY Understanding ViewState

Wednesday, November 29, 2006 3:31 AM by Ruben Cordoba

InfinitiesLoop -- Have you received my comments about the Gridview simplified full version? Do you think I found an ASP.NET bug? All my experiments about getting LinkButton_RowCommand to be fired inside a dynamic user control inside a GridView row template were failed.

# re: TRULY Understanding ViewState

Wednesday, November 29, 2006 3:25 PM by InfinitiesLoop

Ruben -- I sent you an email asking for you to attach the files. Perhaps you didn't get the email, or I didn't get your reply. Send me an email through the 'contact' form on this blog, then we can communicate privately instead of through this clunky comment form.

# re: TRULY Understanding ViewState

Friday, December 01, 2006 9:48 AM by Juergen Baeurle

Great article! Thanks!

# re: TRULY Understanding ViewState

Friday, December 01, 2006 1:55 PM by JP

I have to disagree with whomever wrote about the humor.  Most tech articles are way, way, way too dry.  The humor keeps me going.

Great article, I learned more than I thought I would, thanks for all the effort it took to prepare it.

# re: TRULY Understanding ViewState

Friday, December 15, 2006 5:31 AM by ReneMT

Like all previous commentators I want to give great kudos to this excelent post! At the moment I mess around with some performance issues on a ASP.NET application and found great support in this. So thanks a lot!

PS: I will mention this post in my German .NET blog for advice-seeking German developers ;-)

# re: TRULY Understanding ViewState

Tuesday, December 19, 2006 3:31 AM by tiBorSyo

Wow! what can i say? great article, indeed!

# re: TRULY Understanding ViewState

Sunday, December 31, 2006 7:37 PM by Gail Lampinen

In response to a submit button, which is capturing a variable parameter on the page, I am dynamically creating (multiple) xmldatasources and dynamically creating gridviews using the xmldatasources, which have a checkbox item in one of the columns. I am querying multiple distributed databases to build the data, and the number of datasets returned varies, which is why I build the gridviews (and their underlying xmldatasources) dynamically. However, all is lost on a postback. I need to save these dynamically created controls to the viewstate (these are not created onload or oninit, but in response to a submit button ...) When a user presses another button, I need to access the checked records and use information from them, however the gridviews, along with their checked checkboxes, are lost on the postback. Is there an easy way to save the viewstate of the dynamically created gridviews?

# re: TRULY Understanding ViewState

Sunday, December 31, 2006 7:47 PM by InfinitiesLoop

Gail Lampinen -- congradulations, you're the 100th commenter to this entry :) And happy new year....

First of all, ViewState of dynamically created controls is saved automatically. The fact the control exists on the page is NOT. There's an important difference there... because the issue you are running into has nothing to do with viewstate at all.

Second... just because you have a variable number of items to create, doesn't mean you have to do it dynamically. That's what a repeater is for! Why not put your xmldatasource and gridview inside the item template of a repeater? All you would need to do is databind that repeater, and volia... all your gridviews and datasources would be created and automatically maintained by the repeater on your behalf.

Give it a shot, if you need help working out the markup details, I will need a bit more detail. Contact me through email if you need help.

# re: TRULY Understanding ViewState

Monday, January 01, 2007 12:43 AM by Wiley

Excellent read.  And for the native English speakers, the humor is a breath of fresh air when trying to research & understand frustrating problems.  Thanks!

# re: TRULY Understanding ViewState

Thursday, January 11, 2007 11:24 AM by Shad

I have a dropdown list which I bind on the OnInit page and its view state is turned off.

The AutoPostBack property of the dropdown list is set to true.

Am running into a very strange situation:

When I change the drop down index the SelectedIndexChanged event is fired(not strange at all till now).

Now if I click on any other button that causes a PostBack on the page the SelectedIndexChanged event is firing as well(very strange).

Any ideas why this is happening and how could it be avoided?

# re: TRULY Understanding ViewState

Thursday, January 11, 2007 12:15 PM by InfinitiesLoop

Shad -- First, the event is meant to fire whenever the index changes and theres a postback, not just when autopostback is enabled. The dropdown uses ViewState to remember what the previously selected index was. That is how it knows whether the index has changed. Since you have viewstate off, it will always think the previous index was 0, so it will fire every postback.

May I ask why you are using the SelectedIndexChanged event? There's probably a different way you can handle it to work around this issue.

# re: TRULY Understanding ViewState

Friday, January 12, 2007 3:27 AM by Shad

Thanx for that information. Well on the SelectedIndexchanged event am using the selected value to retrieve some information from the database and display it on the page.

After what you explained I guess the solution would be to create a custom control derived from the dropdown and override the LoadControlState and SaveControlState events and save the selected value in the ConstrolState of the dropdownlist.

That way it will always remember the previous selected value which will avoid firing the SelectedIndexChanged on each postback of the page. Still I have to implement it to see if it works!! What do you think?

# re: TRULY Understanding ViewState

Friday, January 12, 2007 12:21 PM by InfinitiesLoop

Shad -- that would work, and you'd be able to reuse it for other purposes, so thats a plus. If you were just looking for a quick workaround though, it would be simplier for you to just remember the selected index on the page itself by storing it in viewstate.

Something like this:

protected override OnLoad(...) {

  object o = this.ViewState["index"];

  if(o != null) {

     int oldIndex = (int) o;

     if (oldIndex != ddl.SelectedIndex) {

        // changed!

     }

  }

  this.ViewState["index"] = ddl.SelectedIndex;

}

# re: TRULY Understanding ViewState

Monday, January 15, 2007 12:07 PM by InfinitiesLoop

Reynold -- As long as you are loading the controls each request, they should retain their viewstate automatically. The fact they are loaded dynamically does not mean their viewstate is not maintained, it is. There's probably some other issue, unrelated to viewstate. Read the first paragraph of my article on understanding dynamic controls :)

See if you can boil down the issue into a really simple page and user control or whatever. Get it down to the minimum set of code that still duplicates the problem. Doing that may reveal the problem to you (because you'll remove some code and it will suddenly and mysteriously start working). If not, then you'll have a nice compact "repro" of the problem that you can easily post here or send to me via the contact form.

Either way, we'll figure it out...

# re: TRULY Understanding ViewState

Monday, January 15, 2007 12:12 PM by InfinitiesLoop

Shad --

Certainly caching the data would work, even if the data is constantly changing within the database. But I'm not so sure thats the best thing to do. Devs tend to be afraid of database access for some reason... sure, its best to minimize the calls to the database if you can, but sometimes an extra call is more appropriate, and I think this may be one of those scenarios. If you cached the query from the first databinding, you'll be retaining all the data in memory "just in case" you need it later. But if you don't need it later, it was a waste. If the typical postback is not due to the dropdownlist changing, then you will be typically retaining data that you don't use. An extra database call might make the request slightly slower for that one user, but the server as a whole is better off.

That's just how it is on paper though... in reality, it depends on a lot of factors, so I can't say.

# re: TRULY Understanding ViewState

Monday, January 22, 2007 10:00 PM by Reynold Tucan

Thanks for your help.  After stripping my app down to the bare minimum, I noticed that the EnableViewState flag for the instance of the user control in the default page was set to false.  The obvious things are always the hardest to find and debug!  After setting this to true everything works as expected.

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 4:24 PM by Mithu

Great article! (not saying because I am going to ask your help :). It truly is! ). After reading the article which made lots of sense, I realized that I should be locked permanently for view state crime(s) ;-)

Anyway,  started  fixing the view state issues.   Now I am struck with this problem. The article says that the selected value does not get reset because of disabling the view state but because of the drop down is being bound again. But  if I check the  selected value  in any  event handler, it is empty.  The drop down is not getting repopulated at this point of time. If I enable view state, the selected value miraculously appears. Am I missing something here?

I am completely lost :-(

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 4:31 PM by InfinitiesLoop

Mithu -- if you disable viewstate you need to rebind it every request, are you? If you are, when and how?

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 4:31 PM by mhaemp

Thanks for the great article. It's helpful to know the common mistakes in using viewstate.  When using composite controls, is it better to use the view state for public properties like you suggested in the below code snippet or is it better to delegate it to Child Controls? Thanks in advance for your time.

public class JoesControl : WebControl {    

public string Text {        

          get {   return this.ViewState["Text"] == null ?                        

                    Session["SomeSessionKey"] :              

                     this.ViewState["Text"] as string;        }        

          set { this.ViewState["Text"] = value; }    }

}

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 4:43 PM by Mithu

I am.  Rebinding it in page_load of the child control the first time and from the event handler on the parent control when the events get bubbled up from the child control to the parent.

My child control has a text box, a drop down, and two buttons. I checked the drop down value on click event , it is empty. But the text box has the entered value.  I couldnt understand why.

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 4:48 PM by InfinitiesLoop

mhaemp -- Its better to delegate to child controls if you can. Otherwise you have to worry about the value you store being different than the value in the child control. There are plenty of times where delegating isn't appropriate though, because there may not be a direct relationship between your property and child control properties, in any combination. In those scenarios its best to store it yourself, and then use/consume/dependOn the value of that property as late in the page lifecycle as you can (ideally, Render).

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 4:50 PM by InfinitiesLoop

Mithu -- I'm still not clear on what is going on. You must assign the DropDown's data source and call DataBind on it every request if you are disabling ViewState. Not in response to an event, not in only certain conditions, but always. Perhaps you can post some code that illustrates your problem? Ideally, boil down the code to the minimum set of code and markup that you can while still illustrating your scenario.

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 6:03 PM by Mithu

I have  an user control , say ParentControl in my page. ParentControl contains the search control and some other controls.

The search control has a drop down, text box and two buttons(search and clear). The drop down value comes from the DB. So I thought of disabling viewstate and bind the drop down every time. Because the only time the page gets posted is when the search or clear button is clicked.

I disabled view state on the page , ParentControl and SearchControl.

Parent control contains

private void Page_Load(object sender, System.EventArgs e)

{

if(!IsPostBack)

{

-- code retrieve value from DB.set to variable in user controls --

SearchControl1.BindData();

}

}

private void SearchControl1_Command(object sender, CommandEventArgs e)

{

-- code retrieve value from DB.set to variable in user control --

SearchControl1.BindData();

}

SearchControl contains

private void Page_Load(object sender, System.EventArgs e)

{

if(!IsPostBack)

{

BindData();

}

}

public void BindData()

{

-- code to bind data to drop down, text box --

}

private void btnSearch_Command(object sender, CommandEventArgs e)

{

-- code to bubble up event --

}

If I try to see the value of my drop down and text box in btnSearch_Command, text box still has the value but not the drop down. Why? If I enable view state, I can see the selected value here. I dont know if this is even related to view state.

I checked  the selected value in the client side just before the postback, it is fine.

I hope all this makes sense.

# re: TRULY Understanding ViewState

Tuesday, January 23, 2007 6:22 PM by InfinitiesLoop

Mithu -- you say you will bind it every request, but then you have:

if(!IsPostBack)

That means you are not rebinding the data on postbacks. Since ViewState is disabled, the DropDownList's data will vanish after a postback. You need to call DataBind on it every single request, and you need to do it in OnInit. If you do it in OnLoad, the original problem you quoted me on comes into play, where the selected value is reset each time.

Please also keep in mind that when you call DataBind on a control, you are also in turn databinding all of that control's child controls. So if you call DataBind on a user control which contains a DropDownList, you have just databound that DropDownList, too. Many people don't realize DataBind is a recursive call, and they end up databinding things multiple times. Sometimes all that causes is slower performance, but sometimes it causes problems.

# re: TRULY Understanding ViewState

Wednesday, January 24, 2007 9:33 AM by Sabih

I have a problem. I have a repeater containing controls and data populated through datasource. The problem is if I don't set the datasource and rebind on page.Ispostback then repeater doesn't  call item_command method.

Moreover repeater renders nothing on postback if I don't rebind data.

I think this is something with viewstate. Viewstate is not retained for repeater's child control.

I want to avoid loading data again on post back.

Any suggestion will be highly appreciated. Thanks.

# re: TRULY Understanding ViewState

Wednesday, January 24, 2007 10:27 AM by Mithu

Thanks for the reply Dave!

I do call the data bind every postback. first time in page load then from the parent control after the event bubbled up all the way to the parent. And the user control is nothing fancy just a text box, drop down and buttons.

Anyway I couldn't bind the control in Init() , because the pages are designed in such a way to handle all the db calls, the user controls only bind the retrieved data from the page. The child controls Init fires before the parent control and pages, I couldn't bind the drop down in the child control on Init because I don't have the data available to child at that point of time. So I realized my best bet is to enable view state in this case, unless I am missing some other obvious solution.

I appreciate the help and the article! It gave me a very good understanding of  what to do and what not to do with view state.

# re: TRULY Understanding ViewState

Wednesday, January 24, 2007 1:37 PM by InfinitiesLoop

Sabih -- I'll need more details or code samples. It sounds like you have viewstate disabled on the repeater. Keep in mind that disabling viewstate for a control also disables it for all its children, so you could also possibly have viewstate disabled on the control the repeater is in, or it could be disabled for the entire page.

# re: TRULY Understanding ViewState

Wednesday, January 24, 2007 1:45 PM by InfinitiesLoop

Mithu -- "first time in page load then from the parent control after the event bubbled up all the way to the parent". Sorry, I'm still confused :) What if the postback is caused by something other than the bubbled event, like a seperate button on the parent page? You will lose it. You need to call databind every request, from the same code. Why complicate it by splitting it into two places?

The fact you depend on state info to perform the binding does mean you can't do it from OnInit. That does complicate things. Unless your viewstate on that page is unacceptably large I wouldn't try too hard to work around it, just surrender yourself to it :)

I say that because its much easier than the solution -- you would have to write a custom control for this scenario, or make the dropdown list a dynamic control. That would allow you to bind it later in the request but still disable viewstate... its just, not worth the effort unless you have a big viewstate problem on that page.

I can help you with that if you want to persue it, just send me mail through the contact form so we can take it offline.

# re: TRULY Understanding ViewState

Thursday, January 25, 2007 3:28 AM by GokulDas.K (HTC Global Services)

This article provides every information about ViewState.

Thanks for the same..

# re: TRULY Understanding ViewState

Tuesday, February 06, 2007 4:39 AM by Andy Johnson

Great article which clearly explains the fundamentals.

However, I have a problem with a dynamically loaded user control and viewstate.

I understand about how and where to dynamically load controls and fast forwarding through events when attached to the control tree (and yes I do need dynamically loaded user controls).

If my user control contains a dropdown list with viewstate enabled and populated with list items when first created, then I would expect the list contents to be restored on postback after the user control is recreated (without having to reload the list contents). This does not happen and tracking the page/control events indicates that LoadViewState is called ok before the user control is recreated in the page load but is never called after the user control is created and attached to the control tree. This, of course, could have many repercussions for other dynamically created controls.

I know that creating the user control in OnInit would solve the problem but this is not always possible. Is there a way to 'force' the loading of view state for the user control after the main LoadViewState has been called ?

Thanks in advance.

# re: TRULY Understanding ViewState

Tuesday, February 06, 2007 12:37 PM by Andrei Rinea

Excellent article!!! I like the jokes too although I'm not a native english speaker. (BTW: Which state of US would want "out" ? Texas?).

I've searched the net a lot to find an article like these... Even the MSDN didn't shed enough light on the viewstate mechanism.

Again, congratulations!

# re: TRULY Understanding ViewState

Tuesday, February 06, 2007 1:33 PM by InfinitiesLoop

Andy -- don't worry, it's not a hole in the framework. ViewState is loaded for dynamically created controls in OnLoad, I can assure you of that. You said you only see LoadViewState once, but are you referring to the LoadViewState on the page only? Each control has its own LoadViewState, so you should be looking for it happening within the UserControl.

If you aren't seeing that either then there's another problem going on. It could be lots of things, like maybe the id of the control is different on the postback. I would need to see some code. Feel free to post code here if you can summarize it tightly enough, or use the contact form to send it to me privately.

# re: TRULY Understanding ViewState

Wednesday, February 07, 2007 5:10 AM by ChRoss

Hi Dave, what if the postback target is to another page?

For example PageA.aspx dynamically create a user control, let's say ucC, and I add it in a placeholder plhD (declared), and the postback target of the form is PageB.aspx.

How PageB.aspx can retrieve the values from ucC, because I can load the user control, but cannot add to the control tree. I use PreviousPage property to access PageA.

Thanks in advance

# re: TRULY Understanding ViewState

Wednesday, February 07, 2007 5:33 AM by Andy Johnson

I was tracking page and control LoadViewState and I could see the page LoadViewState called but not the control LoadViewState for the dynamically loaded control.

However, I have solved the problem. By placing the user control creation in an override page LoadViewState function after a call to base.LoadViewState(savedState) it all works OK.

I think the base call allows the page ViewState to be loaded and is, therefore, accessable but the recursive child control LoadViewState is called after the page LoadViewState returns by which time the dynamic controls are created and the ViewState is loaded for all controls.

protected override void LoadViewState(object savedState)

{

       base.LoadViewState(savedState);

       SetupDynamicControls();  // which can use page viewstate

}

# re: TRULY Understanding ViewState

Wednesday, February 07, 2007 10:20 PM by InfinitiesLoop

Andy -- viewstate for dynamically loaded child controls will be loaded even after Page LoadViewState. That plays into the "catching up" with the event cycle feature. Its a primary scenario that ASP.NET expects, so if it's not working there must be something else wrong.

Setup a small test environment (with a completely new project, to avoid outside influence). Try to duplicate your problem by creating a page and control that does nothing but override LoadViewState. Put some text in it too so at least you know its loading.

# re: TRULY Understanding ViewState

Wednesday, February 07, 2007 10:23 PM by InfinitiesLoop

ChRoss -- thats a great question! Its great because I've actually never even tried that scenario before.

The value is null probably because the page doesn't exactly go through its typical processing. But it is a page instance, so you should be able to find the control using FindControl.

You should have access to the placeholder you mentioned... call FindControl('id') on it, where 'id' is the id you give to the UserControl you dynamically loaded. It would work assuming the PreviousPage goes through the life cycle up to OnLoad, which I honestly have no idea about. So I'd love to hear how it goes.

# re: TRULY Understanding ViewState

Thursday, February 08, 2007 12:28 AM by venkatesh

how to get the view state value in page load? could you please help me?

# re: TRULY Understanding ViewState

Thursday, February 08, 2007 1:35 AM by ChRoss

Hmmm... I made a further test.

My user control contains a textbox txtC

Case 1

In PageA.aspx, I have textbox txtA, and also a user control created dynamically on the page load. When submit to PageB.aspx, I can retrieve both textboxes value (txtA and txtC), so all working fine.

Case2

In PageA.aspx, I have textbox txtA and a button. When this button is clicked, I create the user control. When click another button to submit to PageB.aspx, I cannot find the user control (using FindControl). it shows null. I check on the placeholder containing the user control, placeholder.Controls.Count return 0.

So, only if the user control dynamically created after postback, then postback to another page, I cannot retrieve the value.

I'm not sure about the life cycle of the PreviousPage, but how do I "load" again the user control? to retrieve the value.

# re: TRULY Understanding ViewState

Thursday, February 08, 2007 6:16 PM by InfinitiesLoop

Wow I could start a whole 'nother blog just from the comments to this one entry...

Anyway :) Keep them coming people. One of these days I plan to revamp this article and create a sort of FAQ based on all the comments and questions posted here. My ambition is probably bigger than my will, though.. thats a huge task!

ChRoss -- controls have to be loaded every request for them to continue to exist. If you only create a control when a button is clicked, it's not going to exist on requests where the button was not clicked, and that includes cross page postbacks.  What you'll have to do is when you load the user control (in response to the button click), store something in ViewState (with this.ViewState["foo"] = "bar"). The thing you store is for your benefit, because you're now going to override LoadViewState. After calling base, you check for that same viewstate value, and if it exists, and using any context information you may have stored in it, you now recreate the usercontrol. One more thing though -- if the user happens to have been clicking the button during this request, you'd end up loading it a 2nd time. So in response to the button click, you first clear the control collection of the placeholder you are adding it to. That or you find it and remove it -- or you hold on to the instance you created from LoadViewState and use that to remove it. Doesn't matter how, just get it out of there. And finally -- you'll want the IDs of the removed control and the new control to be the same, so don't allow the framework to auto-assign an ID -- give it a specific ID yourself.

# re: TRULY Understanding ViewState

Friday, February 09, 2007 3:34 AM by ChRoss

:) Yes it works! Thanks a lot!

This is my snippet of PageA.aspx:

 protected void Page_Load(object sender, EventArgs e)

       {

           if (ViewState["plhAControl"] != null)

           {

               plhA.Controls.Clear();

               myucC = (ucC)LoadControl("~/ucC.ascx");

               myucC.ID = "myucC";

               plhA.Controls.Add(myucC);

           }

       }

       protected void Button1_Click(object sender, EventArgs e)

       {

           plhA.Controls.Clear();

           myucC = (ucC)LoadControl("~/ucC.ascx");

           myucC.ID = "myucC";

           ViewState["plhAControl"] = "on";

           plhA.Controls.Add(myucC);

       }

# re: TRULY Understanding ViewState

Friday, February 09, 2007 5:12 PM by Scott

Great article. I would like to reiterate a comment left earlier:

It would be useful if you could extend the article to clarify how viewstate is associated with event handlers e.g. the dropdownlist control's SelectedIndexChanged event handler.

Thanks,

Scott

# re: TRULY Understanding ViewState

Friday, February 16, 2007 1:36 PM by Darren

Hi, great article, great site.

I have a page with a tab control (from Telerik - more about that in a bit) which according to the selected tab, loads a dynamic user control into an asp panel.  The tab control has a property tabstrip.selectedtab.id which I read in Page_load and via a simple couple of if statements, load the apropriate user control into the panel.

The controls are assigned a unique ID before being added to the panel.

When I click the first tab, the control is loaded fine and I can work with it as expected (it has a grid and a form), the postbacks are handled ok because the tab control maintains it's selectedtab.id and the control is reloaded on each page_load.  However if I click the second tab the app hits an exception with

'Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.'

This happens at the point where the user control attempts to load.

I can understand why this may happen, in that the viewstate for the first control in the panel was set by the control that was previously loaded and so does not match with the new control loaded in its place.  I just don't know what to do about it!

Can you help?

Darren.

# re: TRULY Understanding ViewState

Saturday, February 17, 2007 8:27 PM by Verinder

THis is a Great Article. I Have one Question though regarding MultiView Control and ViewState.

I have Multiple User control one per view IN MultiView. If i swicth between Views Those Views are Bind (Say i have a Repeater) and shown. Now When i switch back View A from Visible to Non Visible Mode ItemCreated Event is called for Repeater Even though that View is Not Visible.I want ItemCreated to be called in PostBack Only When View IS Visisble . Problem is If it keeps on calling ItemCreated It is a Performance Bolleneck If i Have Lot OF Views in mUltiView on Server side. IN The ItemCretaed Event I Create Dynamic COntrols back for PostBack If DataItem==Null.

How To Avoid Other Views not to do anythng when they are Not Visible???  PLease Answer I am IN Trouble...

# re: TRULY Understanding ViewState

Sunday, February 18, 2007 3:20 PM by InfinitiesLoop

Verinder -- You could load the user control which is in the multiview dynamically. You'd only load the user control which should be visible.

# re: TRULY Understanding ViewState

Sunday, February 18, 2007 3:27 PM by InfinitiesLoop

Darren -- are you giving each user control a unique ID that is always the same? You could assign an ID which is based on the view it is visible in, for example. UC1, UC2, etc. That way at least the ID of the first control and the 2nd control are different.

Now, I'm not exactly sure how asp.net 2.0 handles this scenario. It could be that viewstate is loaded by index, in which case having a different ID won't matter. But if not, then it would. Even if it does load by index I believe there's a way to set it back into loading by ID.

Another solution would be to always load the user control that was visible on the last request. If the selected index has changed, then you then remove the control and load the right one. That may sound like a hack, but I would recommend that approach if you must load them dynamically. Controls just were not designed to be stripped out of the lifecycle mid way like that. By loading the old control first, its viewstate is loaded, and the 2nd control is going to get a fresh start just as if it were a new page request.

If you don't have many views, you could also always load them ALL every request. Then you just make them visible/invisible based on the selected index. That has the advantage of them being able to maintain state. If someone switches from Tab A to Tab B and then back to Tab A again, all the controls on Tab A will still have all the data they did before. A definite plus if it contains form data that the user may have typed things into.

# re: TRULY Understanding ViewState

Sunday, February 18, 2007 5:56 PM by Verinder

Hi,

First of loading the control Dyanmically is not a good solution.I Did that but does require lot of work to make it work. It defeats the perpuse of Wizard or Multiview, Then i can write Multiple pages to escape from that coding. If i have a Wizard With lot of steps and Controls are Bidded as you Go from one Step to other. Suppose i moved from Step 1 to step 5. Now at Step 5 Wizard will have a perfromace hit because ItemCreated Event of all step 1-4 even though i am o Step 5.  I don't know even what is the use of calling Page_Load of each step in Wizar or Multiview When Only One Control is Visible. Looks like a Flaw in Microsoft design.

PLease tell me some elegant solution without Dynamic controls.

Verinder

# re: TRULY Understanding ViewState

Sunday, February 18, 2007 6:22 PM by InfinitiesLoop

Verinder -- and what if the user is on Step 5 but needs to go back to Step 1?

The fact all the controls continue to exist is by design, because it allows them to (1) continue to maintain their state, and (2) you can access them when the wizzard is finished in order to process the information. Controls in general can't just assume they are not going to be visible either, since it is quite possible that you (user code) may make them visible at almost any time. Even so like I said, data in invisible controls is still accessible, and thats a good thing. Visible=false doesnt mean "this control does not exist", it means it isn't rendered into the html, nothing more!

Since you seem not to need the control anymore you must be using the data as soon as they move to the next step -- why? Gather it all at once when they are finished, it would be simpler. If there's reason why you need to do it the way you are, rather than try to remove the control or something you could always just clear the bound data from them, so there are no items to create (controls.Clear, or re-bind it with no datasource).

You are worried about 5 controls going through ItemCreated events? Surely there are more important bottlenecks in your app. A complex asp.net page can have hundreds upon hundreds of controls on it and still perform extremely well, so if thats your only bottle neck you're in good shape. Sorry, it just seems like you're worried about the wrong thing.

The design of the framework may not fit 100% your scenario here, but thats how frameworks are. They meet a great many needs and to some degree allow customization for specific scenarios.

# re: TRULY Understanding ViewState

Monday, February 19, 2007 10:04 AM by OscarD AKA &quot;Joe&quot;

Great Article...

I just found my real job position "would-be shoddy asp.net developer" :P

This has open my mind.

I'm going to code better after this.

Thx a lot

P.S. how did you know I used to be an VB developer, ah? LOL

# re: TRULY Understanding ViewState

Monday, February 19, 2007 10:14 PM by verinder

You are right that ItemCreated Event doesn't cause much of time.. But What i have seen is ViewState of Page Keeps Growing as you Move from one step to other . It contains the ViewState of all the COntrols in each Wizard step once they are bound. So It does increase the Size of page passing through the Wire even though the UI which you are seeing in the step is very simple. I was able to get round this probelm by Enabling the ViewState of View Which i am going to show using StepINdexChanged Event. That Solves the problem.

Thanks a lot!!   My Manager was very worried about having multiviews and Wizards inside multiview can cause the page to slow down. Based on what you said.. I removed all the code from Page_load and Bind the UI which i am going to see on StepINdexChanged Event of Wizard . Along with that i set the ViewState of all Views set to False other then what i am going to show.  That Solves most of the Issue..

My COmpany is very worried about using 10-15 views in one page with each view has its own user control. Based on your opinion i will go ahead and push this Wizard design forward. Other school of though is why can't we do seperate pages and write Wizard like functionality using page logic. My though was well then what is the use of Wizard if we can't use that.

Thanks a lot!

Verinder

# re: TRULY Understanding ViewState

Monday, February 19, 2007 10:25 PM by verinder

Thanks a lot!.. I did see that ItemCreated Event is not very heavy processing wise. What i have noticed is ViewState of page keeps growing and it adds the viewstate of each control on the page as you move step forward, and hence will be heavy on wire even if the view which is showing up uses 10% of hidden field which is out there.  I Used EnableViewState of WizardStep to set the ViewState f step i am going to be in and disable all others. THis clears that issue.

I will try Controls.Clear solution also.  

My Company(Managers) were very concern about 10-15 controls in one page and all doing heavy lifing work. I solved the probelm by removing everything from there Page_load and Call Binding when we go to that step. Also Using ObjectDataSource Declerative DataBinding DataBinding is called by itself when view shows up.

ViewState and ItemCreated solution i resolved by creating WizardBase which Captures StepINdexChanged Event to disable all view state other then active step.

Thanks for telling me that it won't be performance issue because we were thinking to write seperate pages to mimic Wizard.

Thanks

Verinder

Thanks

Verinder

# re: TRULY Understanding ViewState

Wednesday, February 21, 2007 11:17 AM by kurt

Excellent article. Thanks for taking the time to put it together. I found the article while looking to solutions for a problem that I have.

I want to use an editable grid control on a page. The grid rows will be based on the selection in a drop-down. When the page first loads, the drop-down will have a default value, and the grid will be populated based on the default value.

If the user selects another value in the drop-down, I want the grid rows to reload (via callback), taking the user's selection into account (basically rebuilding the grid with a new DataSet). When the user presses the "save" button on the page, how can I get the data to save to the correct new dataset?

I'm not sure if this ViewState article is the right place to ask this question, but any help you could give me would be awesome.

Thanks again for the excellent article!

# re: TRULY Understanding ViewState

Wednesday, February 21, 2007 1:37 PM by InfinitiesLoop

kurt - sounds like you want a two-way binding, which you can do pretty easily with a datasource control. You can even make it work against a custom business layer using the object datasource control. This definitely isn't my strongest area :) But there should be lots of examples out there. Sorry I'm not more helpful than that.

# re: TRULY Understanding ViewState

Wednesday, February 21, 2007 10:57 PM by Verinder

Kurt--I have Done the same thing with ObjectDataSource and With Two way dataBinding . What you need to do is in Button Type CommandName="Update" and Use Two way dataBinding with ObjectDataSource. I have done this with FOrmView not with DataGrid though but concept is same

# re: TRULY Understanding ViewState

Thursday, February 22, 2007 6:30 AM by Graeme Elliott

Excellent article. After 3 years with ASP.NET I finally get what ViewState is REALLY about.

I do have a question though.

I have a UserControl with a property ClassificationName that uses ViewState as the backing. I also have a DropDownList that uses the ClassificationName as a parameter when DataBinding. DataBinding occurs through a Click event handler that sets the ClassificationName property then DataBinds the DropDownList.

I'd like to avoid having the DropDownList writing its contents into ViewState, I would prefer to DataBind the list BEFORE ViewState tracking on the DropDownList kicks in on subsequent requests after the Click event handler has been called.

The obvious problem is that I don't have access to my ClassificationName property until after the Init phase on the UserControl by which time its too late to do this.

Is there an elegent way to achieve this? My best guess is that I need to defer initialisation of the DropDownList control by dynamically adding it to the page after the Init phase is complete and I have access to the ClassificationName property.

Any thoughts would be appreciated.

# re: TRULY Understanding ViewState

Thursday, February 22, 2007 2:00 PM by InfinitiesLoop

Graeme -- yes, you are right that you need to delay initialization of the dropdown by creating it dynamically. I wish there were a non-dynamic way of doing it, but its your best bet.

What you should do is use a viewstate key to store the classification name which you have databound. Then in LoadViewState, after calling base.LoadViewState, you check for that key and if it exists, you create the dropdown, bind it, and add it to the page.

Then, its possible the click event comes through again later on in the request. So you would have to be sure to remove the old dropdown and create a new one. Give each a specific ID that is the same every request, or make the ID based on the classification name. It should work like a charm.

# re: TRULY Understanding ViewState

Tuesday, March 13, 2007 6:13 AM by John

You've spelt "its" wrong in the caption of the star trek ship.

It should be "to its own"

# re: TRULY Understanding ViewState

Friday, March 16, 2007 5:10 PM by InfinitiesLoop

mehmetserif -- Can you post some code?

# re: TRULY Understanding ViewState

Saturday, March 17, 2007 11:03 AM by mehmetserif

Sure

This is the property that i made to count the button clicks and it'll create fileuploads at run-time according to its click numbers

public int ButtonClick

   {

       get

       {

           return (int)ViewState["ButtonClick"];

       }

       set

       {

           ViewState["ButtonClick"] = value;

       }

   }

and then i create the fileupload controls at run-time

protected void lnkEkle_Click(object sender, EventArgs e)

   {

       ++ButtonClick;

       for (int i = 0; i < ButtonClick; i++)

       {

           FileUpload myControl = new FileUpload();

           myControl.ID = "upload_" + ButtonClick.ToString();

           this.panel1.Controls.Add(myControl);

       }

       lblSonuc.Visible = true;

   }

then when i want to upload files by those auto-created fileupload controls i get an nullReferenceException

protected void Button1_Click(object sender, EventArgs e)

   {

           for (int i = 1; i <= ButtonClick; i++)

           {

               myUpload = ((FileUpload)pnlUpload.FindControl("upload_" + i.ToString()));

               if (myUpload.HasFile)

                {

                   upload(myUpload.PostedFile.FileName);

                   lblSonuc.Text = "basari";

                }

           }

   }

So i don't know what to do?

# re: TRULY Understanding ViewState

Saturday, March 17, 2007 4:56 PM by InfinitiesLoop

mehmetserif -- the problem is you are only creating the fileupload controls when the user clicks on the button to add one. If they click on any other button you do not create them, therefore they do not exist. You should read my articles on understanding dynamic controls.

To see what I mean about them not existing, add another button to your page that doesn't do anything. Add some upload controls a few times, then click that button. They will vanish. Controls created dynamically must be added every request, and you're only doing it as long as they click the add button. You will need to override LoadViewState and create them there. The 'add' button then will just add a single control as well as increment the counter.

# re: TRULY Understanding ViewState

Sunday, March 18, 2007 2:39 PM by Masonator

Thanks for a fantastic article. Really helped my understanding.

I have a question though. In the last part of the article when dealing with dynamically generated controls, you suggest adding them like this:

public class JoesCustomControl : Control {

   protected override void CreateChildControls() {

       Label l = new Label();

       l.Text = "Joe's label!";

       this.Controls.Add(l);

   }

}

Which works perfectly for most controls. However, when I try adding Imagebuttons or Checkboxes with this method the Viewstate starts growing. For exmaple,

public class JoesCustomControl : Control {

   protected override void CreateChildControls() {

       Label l = new ImageButton();

       l.Text = "Joe's label!";

       this.Controls.Add(l);

   }

}

causes the Viewstate to grow.

Can anyone explain why this happens, or how to avoid it, as this is causing a huge viewstate in my current project.

Thanks

# re: TRULY Understanding ViewState

Sunday, March 18, 2007 3:18 PM by InfinitiesLoop

Masonator -- ImageButtons use a part of page viewstate to register themselves as postback controls. Unfortunately there's no way to turn that off. The reason it needs to do that is hard to explain in a comment... its basically because the name of the posted value coming from the control in the form fields isn't the same as its ID, so it tells asp.net to raise its postback event anyway. The only way around this I'm afraid would be to write your own image control that doesn't need to do this.

You shouldn't see the same thing for checkboxes, except perhaps if you are hooking into the check changed event.

# re: TRULY Understanding ViewState

Sunday, March 18, 2007 3:53 PM by Masonator

Thanks for the help!

Imagebuttons arent so much the problem as checkboxes. If you try the code above but add a checkbox rather than an imagebutton, the viewstate still grows.

The most annoying thing is that im fairly sure viewstate isnt even needed for the checkchanged event to work, as i have managed to get this to fire correctly even when manually setting the viewstate to the empty string. But then, of course, all the imagebuttons on the page stop working.

Any ideas?

# re: TRULY Understanding ViewState

Sunday, March 18, 2007 5:05 PM by InfinitiesLoop

CheckChanged may fire without viewstate, but it won't work the way you think. It will only fire if the state isn't the declared value. If you hit it, then switch it back again, the changed event won't fire because its the same as the original value. The checkbox will save its value in viewstate automatically if you subscribe to the check changed event (unless its disabled). Are you using that event?

If so consider changing your design not to require the event. Usually it isn't necessary -- why do you need to know when it CHANGES? Usually just knowing what it IS is enough. In all my years I've never needed that event...

# re: TRULY Understanding ViewState

Monday, March 19, 2007 7:42 AM by Masonator

Thanks again for the help. I really appreciate it.

I am using the checkchanged event to cause an update panel to refresh...but actually ive just realised I dont need that because all I really want is AutoPostBack=True....

But I was trying things out on a checkboxlist hardcoded in at design-time and viewstate was still increasing. Do I have to manually disable the event? Or is it enough to simply not speciify a handler?

Again, I really appreciate your help as this is the first asp.net site ive worked on, and I think it could be a really nice site if I can sort out this one issue. To see an example of what I am trying to achieve, see

http://www.bringmeatakeaway.com/MenuViewer.aspx?ShopID=13&CatID=78

and play around with the menu items.

Again, thanks for helping.

# re: TRULY Understanding ViewState

Monday, March 19, 2007 4:40 PM by InfinitiesLoop

Ahhh, yum!

The checkbox knows whether anyone is hooked into the event, so just not hooking it should prevent your viewstate growth. If that's not what you are seeing then grab a viewstate decoder and see what the difference is with and without a checkbox on the form.

# re: TRULY Understanding ViewState

Tuesday, March 20, 2007 11:28 AM by Masonator

Ok...I think im beginning to understand the situation.

The viewstate decoder tells me that every listitem I add in the checkbox list is being added to an array in controlstate called "__ControlsRequirePostBackKey__" and this is whats causing viewstate to grow.

Do you know how I can stop this happening? From what ive read so far, im coming to the conclusion that its impossible to prevent this information being recorded even though, in my situation, its unnecessary.

Any thoughts?

Thanks

# re: TRULY Understanding ViewState

Tuesday, March 20, 2007 1:38 PM by InfinitiesLoop

Ok... I hadn't realized this (thank you). CheckBox calls Page.RegisterRequiresPostback, which puts it into that collection. I'm afraid there's nothing you can do about that. One thing that could help reduce the viewstate size in this case though is to make your IDs short. If you have a repeater inside a datagrid inside a gridview and inside that is a checkbox list, then well the naming container'd IDs get pretty long. Keeping the ids 2 or 3 characters long could have a big impact.

I don't know precisely why CheckBox calls that register method. It may have other purposes, but the purpose I know about for calling that method is when the post data key your control posts doesn't match its unique ID. For example and image button with id 'img1', when clicked on, will post to the server two keys, img1.x and im1.y (representing the x/y coordinates of where in the image you clicked on). Since asp.net can't find a control with that ID it doesn't call its LoadPostData method. But if the control registered that it requires postback, it does.

Checkboxes use their uniqueID as the name which is posted so I don't see why they need to do that. There's probably some scenario I'm not thinking about. I'll dig deeper and see what I can find out.

You could also consider writing your own checkbox control that doesn't do that and see what you get.

# re: TRULY Understanding ViewState

Tuesday, March 20, 2007 2:58 PM by Masonator

Thanks for the comment.

I think I understand the situation now and am just as confused as you as to why it requires this information.

Seems crazy that you have no option to turn it off, either.

# re: TRULY Understanding ViewState

Sunday, April 01, 2007 11:54 AM by serhat

Great article, thanks for the effort.

Would you consider expanding this article with Ajax.net and viewstate relation?

We have relatively large viewstate traffic thanks to our "all inclusive" monster grids. Apart from ones with checkbox column which force us to iterate in entire grid, I guess it will be posible to get rid of grid viewstates all togather.

cheers.

# Rhonda Tipton&#8217;s WebLog Web Links 11.21.2006 &laquo;

Wednesday, May 16, 2007 11:15 PM by Rhonda Tipton’s WebLog Web Links 11.21.2006 «

Pingback from  Rhonda Tipton&#8217;s WebLog Web Links 11.21.2006 &laquo;

# New Developers

Saturday, May 19, 2007 3:21 PM by The Web Gambit

Oren Eini made a great post the other day on his blog about some of the "experienced" .NET developers

# TRULY Understanding ViewState

Wednesday, May 23, 2007 5:09 PM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# re: TRULY Understanding ViewState

Monday, August 06, 2007 6:30 PM by Andrei Rinea

Sorry for being redundant but this is a great article! I read it again and again and today AGAIN and I find new things everyday in it.

This should be the top thing in MSDN related to ViewState.

# re: TRULY Understanding ViewState

Tuesday, August 07, 2007 9:18 PM by Sada

Hi,

Iam having a AddNew Button which shows a panel with following controls with a ddl1,ddl2, a textbox and a save button. When i click on Addnew I populate the ddl1 with values and based on a session variable i get the selectedvalue of the ddl1 ( which i set in PAge_Prerender using ddl1.selectedvalue=_value ) and populate the ddl2 based on the selectedvalue.

      The page is displayed fine. The user selects a value from ddl2 , enters some value in the textbox and click on Save button.

      At this point it calls the SelectedIndexChanged event for the ddl1 which causes the selected value of ddl2 to go away. So My Save_Click event fails at it is unable to get the Selectedvalue of ddl2.

      Iam wondering why the SelectedIndexChanged event is fired.

Also one more thing, the same code works fine in asp.net 1.1 and doesnot work in asp.net 2.0

I have compared the aspx and the .cs files of old and new ( converted ) sources but donot find anything changed with respect to the ddl.

Thanks in Advance for your help

Sada

# re: TRULY Understanding ViewState

Wednesday, August 08, 2007 5:27 PM by Yann

This article blow my mind, just what i needed to definetily understand how to better use dynamic controls !

# re: TRULY Understanding ViewState

Tuesday, August 14, 2007 3:57 AM by rspaz16

Hello, good and amazing article. I have one problem. I have one composite control with one dropdownlist. The control has a property Enabled, she sets Mybase.Enabled to True or False. If Enabled is true, the dropdownlist saves her value correctly on a Postback, but if Enabled is false, the value is lost. Do u know what can the reason be?

Than you and greetings from Spain

# re: TRULY Understanding ViewState

Tuesday, August 14, 2007 12:34 PM by InfinitiesLoop

rspaz16 -- do you mind providing a small sample showing the problem? I don't think disabled controls post their value because the browser doesn't include them in the postback data. But even so, I think the DD should still restore its last value from ViewState.

# re: TRULY Understanding ViewState

Thursday, August 16, 2007 1:57 PM by InfinitiesLoop

Sada -- sorry for the long delay in a reply. Doesn't sound like the event should be firing for your scenario, so there must be something in particular about the code causing it. Do you mind sending me some sample code?

# ASP.NET Case Study: Bad perf, high memory usage and high CPU in GC - Death By ViewState

Monday, August 20, 2007 8:37 AM by If broken it is, fix it you should

I get enough issues relating to bad perf caused by large viewstate that I felt like it is time to dedicate

# TRULY Understanding ViewState

Wednesday, August 22, 2007 1:35 PM by Thomas Kohler's Blog

# Viewstate...

Thursday, August 23, 2007 8:26 AM by My own little space....in the Blogging sphere

This blog entry is not to discuss viewstate, but just to share a few links which I really found useful

# Miriam Masada Blog &raquo; TRULY Understanding Viewstate

Monday, August 27, 2007 12:50 AM by Miriam Masada Blog » TRULY Understanding Viewstate

Pingback from  Miriam Masada Blog &raquo; TRULY Understanding Viewstate

# igorerrolkjd &raquo; Blog Archive &raquo; TRULY Understanding Viewstate

Pingback from  igorerrolkjd  &raquo; Blog Archive   &raquo; TRULY Understanding Viewstate

# re: TRULY Understanding ViewState

Friday, September 07, 2007 3:04 AM by CDP

Excellent detailing.

Humour!!!

I liked this part...in Persisting Cheap Data.

When you said for lot of unnecessay data stored in viewstate which can be done alternatively also...

'I often wonder what it would be like if I explained to my grandmother the reason why her internet is so slow is because her computer is telling the server what all the US States are.'

# re: TRULY Understanding ViewState

Monday, September 10, 2007 10:06 AM by teatime

InfinitiesLoop, great article unfortunately for me it now means I have a motivation to fix all of the problems it has shined a light on with the way I have done things with a current application.

If you ever get the chance it would be useful to read an article specific to the GridView and ViewState.

It would be useful to know what is required to have a GridView with ViewState disabled, that is bound to a datasource (in my case entityspaces) but still allow for extraction of datakeys, sorting, paging etc.

Also to throw a spanner in, the GridView is part of a custom control, which means no access to the preinit event...

# re: TRULY Understanding ViewState

Tuesday, September 18, 2007 11:32 AM by Paul Juenger

Great Article!  A lot of ASP.NET programers come from a windows programming background and fail to understand the lifecycle of an ASP.NET page.  This should be a must read for all ASP.NET programmers.

# 简单说一下ViewState

Wednesday, September 19, 2007 10:03 AM by 颜迪新

在做EasyFramework的时候,对ViewState的控制一直是个问题。后来看了一篇强文《TRULYUnderstandingViewState》之后,才基本搞清楚了。下面照本宣科,把要点说...

# re: TRULY Understanding ViewState

Tuesday, September 25, 2007 2:44 PM by Brandon Croft

I especially like your quip about the browser telling the server what the US states are. The problem with simply binding on every init is this: Many times we have to rebind to allow postback events to be raised from dynamic controls. After the event is raised, its even more common to bind yet again to reflect changes or leave the page entirely. Either way, its a waste of a database trip when you could have just examined the form collection to begin with. This is the fundamental flaw of ASP.NET: event-ignorant pages.

Fun writeup. Well done.

# re: TRULY Understanding ViewState

Thursday, September 27, 2007 4:36 PM by Daniel Bailiff

You mention that we can hook into the Init event of a static control to dynamically set its properties. Such as:

<asp:Label id="Label2" runat="server" OnInit="lblDate_Init" />

However, I'm having problems writing the event handler. The key issue being that the sender object is not initialized so I can't do anything with it!

public void MyObject_OnInit(object sender, EventArgs e)

{

((MyObjectType)sender).SomeProperty = "foo";

}

In the above example, "sender" is null. Can you please provide a code example on how to do this? Thanks!

# re: TRULY Understanding ViewState

Thursday, September 27, 2007 4:43 PM by InfinitiesLoop

Daniel -- works for me. Sender is the control. Perhaps its caused by something else on the page -- are you using a master page? Can you duplicate this with just a simple page with nothing else on it?

# re: TRULY Understanding ViewState

Thursday, October 04, 2007 8:46 AM by Abey

I had a problem few days back. I have couple of user controls which has a method (say method A) which returns the values for the controls (text boxes and dropdowns) inside the user control. I am dynamically loading the user control in my aspx page (by default one user control will be loaded). I have a dropdown in my aspx and when i change the dropdown, the respective user control is loaded after removing the previously loaded user control. But before i load the new user control, i call the method A on the currently loaded user control to get the values of text boxes of user control. I am getting the values properly for the default user control which is loaded. But the problem starts when it tries to call the method A after changing the drop down (ie after a new user control is loaded in dropdown selected index changed method.) The method doesn't return the values which i have entered in the controls. I tried a bit of googling to find out the reason and solution for this.

Some say that its because i am loading the user control in dropdown, your view state doesn't store that user control values, because what ever controls which is dynamically loaded after the LoadViewState method of the page, view state doesn't seems to store the values of those controls. I tried loading the user controls in different events which actually fires before the loadViewState, but no use.

Though i didn't get a proper solution to the problem, i partially solved it by using the request object in method A of user control. For eg: you can use Request["your textbox id"] , which will give you the values you have entered.

This one i actually posted in my blog

blogs.ittoolbox.com/.../user-control-not-persisting-the-value-19410

# re: TRULY Understanding ViewState

Thursday, October 04, 2007 9:08 AM by Abey

And Awesome blog on viewstate

# Rob&#8217;s World &raquo; Truly understanding ASP.NET

Thursday, October 04, 2007 9:21 AM by Rob’s World » Truly understanding ASP.NET

Pingback from  Rob&#8217;s World  &raquo; Truly understanding ASP.NET

# re: TRULY Understanding ViewState

Thursday, October 04, 2007 10:43 AM by H Canberger

Hi!

After trying to optimize view state usage on my custom controls I realized that the pattern for properties persisting its data in the view state, used on most controls in System.Web.UI.WebControls, is far from optimal. If you look at your TextBox's ReadOnly property it's implemented like this:

public virtual bool ReadOnly

{

  get

  {

     object obj =ViewState["ReadOnly"];

     if (obj != null)

     {

        return (bool) obj;

     }

     return false;

  }

  set

  {

     ViewState["ReadOnly"] = value;

  }

}

Much like your Text property example above.

If you set ReadOnly=true after the TextBox control has started tracking changes to its view state, the value will go into the hidden __VIEWSTATE field. Just like it should.

If we set it to ReadOnly=false it will do the same. Why? This time it's unnecessary to persist the false value in the hidden field, since the get accessor will default to false if the value is not in the ViewState statebag.

So, if we set the property to its default value, according to what get returns, there’s no need to persist it to the hidden field and therefore we can set the dirty flag to false.

In the example below I’m using a constant for the default value, and a shorter get-accessor than above, besides the changes of the set accessor.

private const bool _Default_ReadOnly = false;

[DefaultValue(_Default_ReadOnly)]

public virtual bool ReadOnly

{

  get

  {

     object obj =ViewState["ReadOnly"];

     return obj!=null ? (bool) obj : _Default_ ReadOnly;

  }

  set

  {

     ViewState["ReadOnly"] = value;

     //When setting the default value, there’s no need

     //to persist it in the viewstate field

     if(IsTrackingViewState && value == _Default_ReadOnly)

     {

        ViewState.SetItemDirty("ReadOnly", false);

     }

  }

}

This way no unnecessary data will go into __VIEWSTATE.

One might say that setting properties will take longer. Sure, it will, but in total it must be shorter than serializing and deserializing the data.

Dave, any thoughts? Is this pattern safe to use? I haven’t seen this pattern on the net so I’d be happy for any feedback.

# re: TRULY Understanding ViewState

Thursday, October 04, 2007 1:35 PM by InfinitiesLoop

Abey -- you say you dont get the values you want when you call A() on the newly loaded user control. But when exactly are you calling it. You make it sound like you're calling it right after loading it, but then the user hasn't had a chance to enter anything yet.

A control created after LoadViewState will still load its viewstate, so whoever told you that is wrong :) There's no reason this shouldn't work, if it's done the right way. The main thing would be to make sure you're always loading the control that previously was loaded, and the best place to do that would be from LoadViewState. If you follow the pattern I describe in Part 4 of my article on understanding dynamic controls it should work.

# re: TRULY Understanding ViewState

Thursday, October 04, 2007 1:41 PM by InfinitiesLoop

H Canberger --

I have thought the exact same thing in the past. But there is one scenario where it's important to store the value even though it is the default. Imagine you have:

<asp:Foo runat="server" Visible="false" />

Visible is true by default. Since this is just the declared value, it won't be saved into __VIEWSTATE. Now dynamically set Visible to true.

foo.Visible = true;

If the Visible property said hey, thats my default value, so just remove the viewstate entry, then what do you think would happen on the next postback?

<asp:Foo runat="server" Visible="false" />

Sets it to false... and then since there's no entry in the dirty ViewState for it, it stays false.

So its important to store the value even if its the default, because it also tracks changes from the natural, declared state of the control.

# Olga Talks &raquo; Blog Archive &raquo; TRULY Understanding Viewstate

Thursday, October 04, 2007 1:50 PM by Olga Talks » Blog Archive » TRULY Understanding Viewstate

Pingback from  Olga Talks  &raquo; Blog Archive   &raquo; TRULY Understanding Viewstate

# re: TRULY Understanding ViewState

Friday, October 05, 2007 3:22 AM by H Canberger

Thanks for your comments. I knew the pattern was to good to be true. :)

# 理解ViewState

Friday, October 05, 2007 4:16 AM by 笼民

从页面的Init阶段开始,ASP.NET会监视哪些控件的哪些属性被动过了;一旦有属性在Init之后被动过了,就会被扔到页面上的__VIEWSTATE隐藏字段里去。

# Computers &raquo; TRULY Understanding ViewState - Infinities Loop

Pingback from  Computers &raquo; TRULY Understanding ViewState - Infinities Loop

# Thoughts on the ASP.NET ViewState

Monday, October 08, 2007 4:37 PM by Emil Stoichev's Blog

Last week I've attended the DevReach conference in Sofia, Bulgaria. It is one of the few international

# re: TRULY Understanding ViewState

Tuesday, October 09, 2007 9:27 AM by Krivonos Vitaliy

Thanks the auther for this great article! It is one of the most helpfull I've ever read. It helped me a lot.

# Master Page and PreInit

Tuesday, October 09, 2007 10:03 AM by Community Blogs

Emil Stoichev reminded today that it is very important to understand what is ViewState , how it works

# re: TRULY Understanding ViewState

Monday, October 15, 2007 3:26 PM by Rob

Great Article but I must have missed something because I can’t seem to get my viewstate to retain the data after postback

I have a repeater with some form fields in there and an add button to add a extra repeater item, If I press the add button the page reloads and add a extra repeater line but it will repopulate the data of the first line after postback  any ideas?

<%@ Page Language="VB" EnableViewState="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/.../xhtml1-transitional.dtd">

<script runat="server">  

   Dim number_of_Parcels As ArrayList = New ArrayList()

   Protected Sub form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles form1.Load

       If Not Page.IsPostBack Then

           Session("PCount") = 1

           Create_Parcels()

       End If

   End Sub

   Protected Sub Add_Parcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Add_Parcel.Click

       Session("PCount") = Session("PCount") + 1

       Create_Parcels()

   End Sub

   Protected Sub Create_Parcels()

       For a = 1 To CInt(Session("PCount"))

           number_of_Parcels.Add(1)

       Next

       Repeater1.DataSource = number_of_Parcels

       Repeater1.DataBind()

   End Sub

</script>

<html xmlns="www.w3.org/.../xhtml">

<head runat="server">

   <title>Untitled Page</title>

</head>

<body>

   <form id="form1" runat="server">

   <div>

   <asp:Repeater ID="Repeater1" runat="server" EnableViewState="true">

       <HeaderTemplate>

           <table style="width: 100%;">

           <tr>

               <td>Packaging Type</td>

               <td>Length x Width x Height</td>

               <td>Weight:</td>

               <td>Number of Parcels:</td>

           </tr>

       </HeaderTemplate>

       <ItemTemplate>

           <tr>

               <td><asp:DropDownList ID="Packaging" runat="server">

                   <asp:ListItem>Your Packaging</asp:ListItem>

                   <asp:ListItem>Express Envelope</asp:ListItem>

                   <asp:ListItem>Plastic Pack</asp:ListItem>

                   <asp:ListItem>Small Box</asp:ListItem>

               </asp:DropDownList></td>

               <td><asp:TextBox ID="Length" runat="server" Columns="5" EnableViewState="true" ></asp:TextBox>&nbsp;X&nbsp;<asp:TextBox ID="Width" runat="server" Columns="5" />

                   &nbsp;X&nbsp;<asp:TextBox ID="Height" runat="server" Columns="5" /></td>

               <td><asp:TextBox ID="Weight" runat="server" Columns="5" />&nbsp;<asp:DropDownList ID="WeightType" runat="server">

                   <asp:ListItem>lb</asp:ListItem>

                   <asp:ListItem>Kg</asp:ListItem>

               </asp:DropDownList></td>

               <td><asp:TextBox ID="Parcels" runat="server" Columns="5" /></td>

           </tr>

        </ItemTemplate>

        <FooterTemplate>

           </table>

        </FooterTemplate>

       </asp:Repeater>

       <asp:Button ID="Add_Parcel" runat="server" Text="Add Parcel" />

   </div>

   </form>

</body>

</html>

# re: TRULY Understanding ViewState

Monday, October 15, 2007 3:36 PM by InfinitiesLoop

Rob -- this is not an issue with retaining ViewState. When you databaind a repeater, you're telling it to start fresh. It throws away everything and binds the new UI to the data in the datasource.

If you want to save what was changed in the repeater's items you'll have to get them out and put that data into the datasource you're binding to, then add your new item and rebind it.

# re: TRULY Understanding ViewState

Thursday, October 18, 2007 4:12 PM by Rony Klachko

Hi, great articel but I still need some help.

Using the designer I created a Page that contains a GridView databinded to an XMLDataSource. One of the GridView columns is an TemplateItem containing a dropDownList binded to an ObjectDataSource. The selectedValue of the dropdownlist is binded to the value of one of the gridview's columns. All of this is done by the at design time.

I encountered some problems:

1. While ViewState was enabled my page has loaded with a very very big _VIEWSTATE attribute even before tuched any of the controls.

2. To avoid this and as I have no real need for the viewstate I have disabled it on both GridView and dropDownList and both of the DataSources. But than encountered an Exception on my first page postback. The exception was caused by an empty XmlDataSource, and seemed to happen before reloading the page. I temporerly solved that by assigning an event handler for GridView_Init and inside it assigning the XML to the DataSource. (but this solution causes the pulling of this xml from the server excessively).

3. Both before and after disabling the viewstate I had problems preserving the dropdownlist selected value after posting.

I hope I was clear about what I have done and what are my problems, and hope even mroe, that you can shed some light on my issues and help me solve them.

# re: TRULY Understanding ViewState

Friday, October 19, 2007 2:52 AM by Navdeep Bhardwaj

Great article, helped in gaining a lot new. Thanks

# re: TRULY Understanding ViewState

Wednesday, October 24, 2007 4:00 PM by InfinitiesLoop

Rony -- without viewstate, the grid is going to re-bind on every request. That means for sure the datasource needs to be available every request. One way or another, the grid needs to repopulate, either from viewstate or from the data itself.

Also the fact it will rebind on every request means the dropdown is rebinding, too. Rebinding means losing the existing user state, such as dropdownlist selected index or textbox values. The trick is to rebind before these controls load the user state (the postback data), by doing it from OnInit. So you'd just call GV.DataBind() from OnInit rather than allowing the GV to bind itself automatically.

# re: TRULY Understanding ViewState

Thursday, October 25, 2007 11:29 AM by jatin

I read  an article "Understanding ASP .Net ViewState" on MSDN. However I have one query regarding the statement in this article.I hope you will help me to understand.

Under section “Parsing the View State".

It says “The SavePageViewState() method starts by creating a Triplet that contains the following three items:

1. The page's hash code. This hash code is used to ensure that the view state hasn't been tampered with between postbacks. We'll talk more about view state hashing in the "View State and Security Implications" section.

2. The collective view state of the Page's control hierarchy.

3. An ArrayList of controls in the control hierarchy that need to be explicitly invoked by the page class during the raise postback event stage of the life cycle.  “

I have understood point 1 and 2 however in  point no.3 , I failed to understand which controls are needed to be explicitly invoked and why are they needed to be mentioned in viewstate ?? how are they getting populated ? who is populating them ? Does array list of controls mentioned in Point no. 3 is in context of  dynamic controls?

I have analyzed view state of the  DataGrid using Viewstate parser and the third node of triplet appears to be null  and same thing is observed when  I checked it for sample application with button , textbox and dropdown list on forms.

msdn2.microsoft.com/.../ms972976.aspx

# Understanding what Page.RegisterRequiresPostBack does

Thursday, October 25, 2007 1:35 PM by Infinities Loop

I recently received a comment in my Truly Understanding ViewState article about the "ArrayList of controls

# re: TRULY Understanding ViewState

Thursday, October 25, 2007 1:37 PM by InfinitiesLoop

Jatin -- an excellent question. One the deserves its own blog entry, I'd say! Check it out! Thanks for the idea for a post.

weblogs.asp.net/.../understanding-what-page-registerrequirespostback-does.aspx

# re: TRULY Understanding ViewState

Friday, October 26, 2007 2:38 AM by Anil

Hi all,

 I have the Attachement.Ascx control in the Mail.Aspx page,

Which is Loaded in PlaceHolder on the Page_Load, which is in the Formview

In  Attachement.Ascx i have the ListBox were I am adding the Items to  the listBox on the button click,

 for the firstTime the item is added it is visible in the listBox but when I click the Button to add the secound Item into the ListBox the firstadded item is lost on, OnPostBack.

  I have tried with True/False for EnableViewState,

On every Post back the listBox items is Null.

# re: TRULY Understanding ViewState

Saturday, October 27, 2007 11:14 AM by Tim

I'm quite late to the party reading this, but thanks HUGELY for writing this up, and doing it in an informative *and* entertaining fashion (often the best way to get a point across is through facts presented in a way that doesn't just present facts).

I disagree with the individual above who suggests that someone should write in 'a particular way' for one particular reader's culture. If I'm reading a Danish article, I don't presume indignantly that Danes should avoid humor or any other literary device simply because I, of a different culture, might read it. That would be truly arrogant on my part.

Anyway, viewstate is much clearer to me now (after all these years)!

# re: TRULY Understanding ViewState

Saturday, October 27, 2007 1:10 PM by Dave

I am investigating a performance nightmare we are having and I think it could have something to do with viewstate.  We were getting alot of viewstate errors and the coders have gotten those to stop, but our performance is dismal.  We spent the last month optimizing our code for SQL, but it's made no change in performance.  Your viewstate madness graphic matches our source view EXACTLY.  Nutty looking cat upchuck of characters.  I am not a coder (many years designing though and good knowledge) but I have spent a TON of money (measured in gold bullion) on trying to figure out the performance problem.  The db has 400K records, but we have broken things into smaller tables.  Nothing seems to help.  I am not real sure the coder knows some of these advanced/proper uses of viewstate for instance.

Looking at our view source of one of our sites, www.sarasotaguide.tv I am not sure if you can tell if viewstate is our problem, but after reading this article it smells like it?

Thanks for the great article.  I have passed it along trying to give us a better understanding.

# re: TRULY Understanding ViewState

Saturday, October 27, 2007 3:11 PM by InfinitiesLoop

Dave -- the viewstate size on your main page is about 25kb. Thats pretty big, but it's not so big that you'd have a "nightmare".

What I noticed though was that your page took like 4 minutes to finally come through. And the size of the HTML of the front page is about 160kb. Thats huge and sure to drive dial-up users away. Interesting the bulk of the size of your HTML seems to be that tree view on the left. You're obviously using Telerik Rad Controls. Those controls are great but their richness comes with a cost.

Still all of that doesnt explain why it took 4 minutes to respond. To figure that out it would take some debugging. Sounds like the server is doing much more than it needs to, like executing a lot of SQL queries where it could cache the results or consolidate them into one query. Some SQL Profiling would help with that. Send me a private mail and we can dig deeper.

# re: TRULY Understanding ViewState

Sunday, October 28, 2007 11:01 AM by Robert

Hello,

I know that it is possible to rebind a dropdownlist on every request in the Init event and the ddl gets the selected index. But I have the problem that this does'nt work in the ASP:Wizard Control - Why?

I have only a problem with some big (130 rows) dropdownlist resulting in a large viewstate - all other works fine. I only want to "remember" the last selectedindex.

regards

# re: TRULY Understanding ViewState

Sunday, October 28, 2007 6:27 PM by InfinitiesLoop

Robert -- are you sure nothing else is re-binding it later on? Remember that databinding is recursive -- if the DDL is within the Wizard and something calls DataBind on the wizard, it's binding the DLL too.

# Aphrodite Roland Diary &raquo; Archive &raquo; TRULY Understanding Viewstate

Pingback from  Aphrodite Roland Diary  &raquo; Archive   &raquo; TRULY Understanding Viewstate

# Conosciamo bene il viewstate?

Wednesday, October 31, 2007 3:44 AM by AlbLog - Il blog di Alberto Dallagiacoma

Conosciamo bene il viewstate?

# Interessante articolo sul ViewState &laquo; Cosa importa se&#8230;.

Wednesday, October 31, 2007 9:31 AM by Interessante articolo sul ViewState « Cosa importa se….

Pingback from  Interessante articolo sul ViewState &laquo; Cosa importa se&#8230;.

# ViewState: la soluzione finale

Saturday, November 03, 2007 6:54 PM by Theswra and his breathing space

Nonostante si faccia un gran parlare di MVC, MVP a altre soluzioni (leggi pattern piuttosto che soluzioni o modalit

# re: TRULY Understanding ViewState

Monday, November 05, 2007 8:40 AM by Adam

Whats all this "you've been kicked in the knee (thats a good thing?)" Good article.

# re: TRULY Understanding ViewState

Monday, November 05, 2007 12:28 PM by InfinitiesLoop

Adam -- That's "dotnetkicks". Basically a social bookmarking site for .net

# Browsers, processes, cookies and session state

Tuesday, November 06, 2007 4:46 AM by Jon Sayce

Opening the same web page in multiple browser tabs or windows can cause some serious problems if that

# Deva Magazine &raquo; Blog Archive &raquo; TRULY Understanding Viewstate

Pingback from  Deva Magazine  &raquo; Blog Archive   &raquo; TRULY Understanding Viewstate

# re: TRULY Understanding ViewState

Tuesday, November 20, 2007 3:57 AM by Dave Bartlett

This is fantastic - I was getting tidied in knots trying to create a dynamic multiview & you have saved me hours  - I'm off to the beach now!

# RodeoFive &raquo; The ULTIMATE ViewState Tutorial

Friday, November 30, 2007 8:48 AM by RodeoFive » The ULTIMATE ViewState Tutorial

Pingback from  RodeoFive &raquo; The ULTIMATE ViewState Tutorial

# re: TRULY Understanding ViewState

Tuesday, December 11, 2007 10:21 AM by teatime

InfinitiesLoop can you recomend any articles on getting a GridView to work without ViewState enabled? By work I mean, Paging, Sorting, Editing and Selecting rows... to complicate matters, the GridView is embedded in a custom control and most respond to events on another control.

The example I am working on is with my page being split into a Master/Detail format. The Master section contains a custom control that has fields in a form layout. The detail section contains an AJAX tab control, with each tab containing a custom control in the form of a list, using a GridView and here is where my hell began...

# re: TRULY Understanding ViewState

Tuesday, December 11, 2007 6:42 PM by Paul

Infinity -

Thanks for the article.  I want to set some Control attributes that are basically static.  I do not want these properties tracked by ViewState because that would be a huge waste.  So, I do something like:

 protected override void  OnPreInit( EventArgs e )

 {

   base.PreInit(e);

   userName.Attributes["onfocus"] = "getHelp('userName','Help1')";

   email.Attributes["onfocus"] = "getHelp('email','Help1')";

   ...

 }

This doesn't work, .net complains since userName is null.  MasterPages seem to be blameworthy.  However, it works if I do something like this:

 protected override void  OnPreInit( EventArgs e )

 {

   MasterPage master = Master;

   base.PreInit(e);

   userName.Attributes["onfocus"] = "getHelp('userName','Help1')";

   email.Attributes["onfocus"] = "getHelp('email','Help1')";

   ...

 }

Seems that Master.get somehow makes everything initialized.   I'm assuming that it somehow forces construction of the MasterPage object and reshuffles the controls/contentholders.

So: What should I do.  Referencing this.Master on all my my pages in preinit seems like a hack.  The only other option I can think of is to perform this option in Render() before calling base.Render().  I suppose a good option would be to share a subclass of Page that has an OnRender() stub.  

Any Ideas?

# re: TRULY Understanding ViewState

Tuesday, December 11, 2007 8:56 PM by InfinitiesLoop

Paul -- indeed I have seen that Master Page problem. I'm afraid that's just how it is, OnPreInit as far as I know was only intended for dynamically setting the master page (one reason why it isn't a control event).

But actually I would probably do it in Render like you suggest anyway. That way the data can be up to date if something during the processing of the form needs to change it. Render is safe as far as viewstate goes obviously since its after its already been saved with SaveViewState.

# re: TRULY Understanding ViewState

Wednesday, December 12, 2007 8:09 PM by Paul

Thanks infinity,

I want all of my "life cycle handlers" to look consistent, therefore, I did the following.  Hopefully this helps someone later on.  

class MyPage {

 ..

 protected override void Render( HtmlTextWriter w )

 {

   base.Render(w);

 }

 protected virtual void OnRender( )

 {

 }

 ..

}

I don't actually name it "MyPage", but this is the base class of all my pages.  If you are inheriting from Page and not a subclass, then I recommend refactoring since alot can be accomplished at this level.

My subclasses, then, look like:

class AwesomePage {

 ...

 protected override void  OnRender( )

 {

 userName.Attributes["onfocus"] = "getHelp('userName','Help1')";

 email.Attributes["onfocus"] = "getHelp('email','Help1')";

 base.OnRender() // Not necessary, but good habit

 }

 protected override void OnInit( EventArgs e )

 {

 ...

 }

...

}

Now, I just need to figure out why my password-mode textbox's value is not being persisted through multiple postbacks.  I have a MultiView and I want to hold onto a password entered on the first view. I have ViewState enabled.  It is odd how ViewState acts one way with some controls, and another way with other controls (MasterPages, PasswordMode TextBoxes)

# re: TRULY Understanding ViewState

Wednesday, December 12, 2007 8:26 PM by InfinitiesLoop

In password mode TextBox does not remember the password on purpose. Whether you like it or not, that's just how it was written. I think thats a fair feature though, you wouldnt normally want that password to hang around and have to be cleared manually.

If you look at its implementation of AddAttributesToRender you'll see what I mean. I suppose you can just derive from it, override AddAttributesToRender, and make sure the Value attribute is added. ViewState still remembers the value of course, but since the TB is empty after 1 post, the 2nd post clears it out, even in ViewState (just as if the user cleared it themselves).

# re: TRULY Understanding ViewState

Monday, December 17, 2007 1:19 PM by Paul

Hum, I guess I will just hold on to the password in session state and clear it out after submitting the form.  Thanks.

# re: TRULY Understanding ViewState

Monday, December 17, 2007 1:25 PM by InfinitiesLoop

Paul -- dont use session state, just use viewstate.

ViewState["Password"] = txtPassword.Text;

But even that isn't needed if you implement what I said with AddAttributesToRender.

# Understanding viewstate

Friday, December 21, 2007 5:13 PM by patrickfryer.me.uk

Understanding viewstate

# re: TRULY Understanding ViewState

Friday, December 28, 2007 1:09 AM by Raoul

[MCTS Self-paced training kit (Exam 70-528), Microsoft Press, Page 501

As you might have already noticed, if a user clicks a button to submit an ASP.NET page, the page retains all its values and settings. For example, if you modify the text on a label and the user clicks a button, the modified text is still displayed when the page reappears. This happens because ASP.NET has a client-side state management technique built in: ViewState.

]

So this is totally incorrect statement? Thanks.

# re: TRULY Understanding ViewState

Saturday, December 29, 2007 4:47 PM by InfinitiesLoop

Raoul -- no thats completely correct. Why do you think not?

# DropDownlist ViewState problem

Wednesday, January 02, 2008 10:39 AM by Blog de Jérémie Clabaut (ak MinSou)

Today, for performance reason, I decided to remove the viewState on all my dropDownlist controls.&#160; In my webForms there are 5 dropdwnlist with 100 ListItem in each. So the ViewState is very large.... But I ran into a big problem. The dropdown will

# Optimisation du ViewState - l'enregistrer sur le server via le SessionPageStatePersister

Wednesday, January 02, 2008 10:46 AM by Atteint de Javascriptite aiguë [Cyril DURAND]

Il y a quelques temps je vous avez expliqué comment modifier la façon dont le viewstate est enregistré

# re: TRULY Understanding ViewState

Thursday, January 03, 2008 4:01 AM by Raoul

Thanks for coming back. Your statement at the beginning of the article [Then there's this W3Schools article on ViewState that seems to indicate that posted form values are maintained via ViewState, but that's not true.]

seems to contradict

[MCTS Self-paced training kit (Exam 70-528), Microsoft Press, Page 501 - the page retains all its values and settings. This happens because ASP.NET has a client-side state management technique built in: ViewState]

?

# re: TRULY Understanding ViewState

Thursday, January 03, 2008 2:33 PM by InfinitiesLoop

Raoul -- you're painting a broad brush. Both statements are true. ViewState is only one way controls maintain values across postbacks. Regular good ole HTML FORMS play a role, too. For example, disable viewstate on a textbox, and it will still maintain its value, because it is POSTING the value with the form. Make that TextBox invisible then do a post, and the value is lost. Thats where ViewState helps, which would allow it to maintain the value even if its invisible.

# 深入理解 ViewState

Thursday, January 17, 2008 1:25 AM by tsky0722

ASP.NET 、Web 、*Comprehensive Understanding*

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 1:41 PM by Jakub Anderwald

Hi, thanks for this article. It's really great.

I'm just new to ASP.NET, learning everything I can. I used to write in PHP. The more I read about Viewstate, I'm getting just one thing on my mind: don't use it, remove completely. It creates a lot of issues / problems. It throws tons of data to the user and back. But this is not that bad, when used properly. The worst thing is that it makes your server application depend on some encoded / hidden data being sent by user.

I find it unacceptable for a client / server architecture application to depend on the client to work properly. I think it's unsecure by design, no matter how many compensating controls we put on it, it's unreliable, and it's throwing a lot of overhead for nothing.

To me any application that depends on keeping configuration data on client-side is, sorry for the word, lame. I believe that every data should be repopulated on server-side on every client request. If it's from a database query or an internal application cache, it doesn't matter - it's just a matter of how much code would you write for sake of performance and database profiling.

Some really expensive to get data can be cached either in session (when they're per-user by nature) or in some application-wide cache (when they're global), but NOT sent to user and asked to be sent back. I really don't understand why Microsoft is forcing this faulty method.

If I'm just wrong with some basic stuff and reading the whole thing from the wrong side, please correct me. But it doesn't make any sense to me.

Plus, I'm a bit shocked by the lack of understanding of client/server architecture in some of the developers commenting here. To me, always, a developer was a master of the technology he was using - he had not only to use it, he was supposed to tell it what to do. And here I find people who are devleopers just because they can click some fancy controls in IDE.

I just hope they won't be writing my next-gen car computer software ;)

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 1:54 PM by InfinitiesLoop

Jakub -- Thanks for your comments.

As a rule in a lot of ways I agree with you -- its far better to repopulate data on every request than to have it stored on the client.

But...

Storing data on the client... that is not what ViewState is all about. That is what it does, but what data you put there is up to you, if you use it correctly.

Take forinstance an accordian control, common to many menu systems. You click a category and it expands to show a sub-menu. Ok, now over on the other side of the page you type in your email address and click submit in order to add yourself to the site's monthly newsletter. Oops... now the accordian has collapsed again. Thats not what the user wanted. Better if that menu could have remained in the same state. That is the kind of thing ViewState is great for. It's transient data that is only useful within the context of this single page for this single user, and only while the user is on this exact page. Imagine if you had to store that piece of data in the users session. It seems harmless -- but with millions of users, that adds up to a lot of data. Data which will hang around for the user's entire session length, even though its only used for a few seconds! ViewState in this case is a _far_ more efficient way to maintain that kind of state information.

Microsoft is not forcing anything. In my opinion it would have been better if ViewState was always off by default, or if you had to write some explicit code to get data in and out of viewstate. But it being on by default is a long way from 'forcing' anything.

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 3:16 PM by Jakub Anderwald

Two things here:

1/ I had a look at the Accordian and I think it should be expanded at the current navigation level, ie. where you currently are. And as far as I saw, it's quite easy to see in ASP.NET where you are thanks to the web sitemap etc. So I see no reason to store it somewhere.

I see your point here: keep only some not critical data, and let your application gracefully degradate when that data is not available. But it still "doesn't speak to me", as we say in Poland ;) See - if I read your post correctly, you have to take care about deleting that data after it's been used, while in session it would simply expire. And RAM is quite cheap these days, while amount of data flowing in/out of your connection is not.

Plus, POST is not the only way to interact with your page - there are regular GET requests, there are F5-refreshes, there are users who can manually type / paste a link to another part of your site - I would loose the whole ViewState then. Still, I can't see any valid reason to use it.

2/ My friend was playing with VS2008 and ViewState / controls and he was not able to remove it completely. Turning it off in web.config and on control level didn't remove it completely, just made it shorter. I think we'll use the decoder to see what's inside.

He found just one way to remove it at all - overwrite some default functions, so that they return null. But even then, you get the input field in your form.

So yes, it looks like forcing to me ;)

If we're wrong at what we're doing - we're just learning, you know - please correct me. I'll ask him to comment here as well detailing what he did.

Also - a great note about the note that FORMs populate themselves with client-provided data without Viewstate and that ViewState it's not about that. When I asked a coworker who wrtoe a couple of ASP.NET sites what ViewState is really useful for, he said that it allows the site to repopulate all the data in a form that a client submitted just before.

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 3:31 PM by InfinitiesLoop

An accordian was just a contrived example. If you can make it do the right thing without storing data, great. But not all accordians are used for menuing. What would you do then?

Yes ram is cheap, but server resources are precious. You have to think about not only the amount of data you are saving, but how long it is resident for. If a session is 20 minutes and you are storing 100 bytes, thats 2000 byte-minutes, regardless of how long the user is actually on that particular page. If you store that same 100 bytes in viewstate, it only actually consumes server memory when the user actually posts the form. A user isn't likely to sit there on the same page posting it over and over again for 20 minutes are they? You'll get far less byte-minutes on the server. It seems trivial, but image 1000's of users on the site at the same time. That can quickly add up to many megabytes worth of data for something so trivial and simple.

You can't completely get rid of viewstate. It is absolutely required in some situations by the framework. You might scoff at the notion that it is required for anything, but it is, and it has good reasons. And better to use a single hidden field for the required data -- yet somehow I doubt people would complain about it if this 'required' data were stored in a differently named field or fields. Read my post on what Page.RegisterRequiresPostBack is used for as an example.

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 4:32 PM by Jakub Anderwald

What most of the websites do - create menus. Using (X)HTML / CSS styled list. That's all that's required to create a menu ;)

Is ViewState required to be sent to user, or is it enough to be active during the page generation and processing? I'm thinkg of getting rid of it totally from the geenrated content. I don't  mind sending an empty __VIEWSTATE field, but I don't like the idea of having elements in my application, that are "absolutely required" to be sent to client and then sent back via POST. What happens when we use simple links or AJAX to fetch more data? Would the "absolutely required" data be there? Not really.

But - I am open to read more ;) There have been times when I thought of something as totally weird, unnecessary, wrongly designed, and then I found out that it's actually OK in some circumstances. Can you guide me somewhere?

Thanks a lot.

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 4:49 PM by InfinitiesLoop

>> What happens when we use simple links or AJAX to fetch more data? Would the "absolutely required" data be there? Not really. <<

Sure it will. If you use an UpdatePanel. And if you dont use an UpdatePanel, then there isn't any update from the server anyway, and there is no viewstate to update.

>> But - I am open to read more ;) There have been times when I thought of something as totally weird, unnecessary, wrongly designed, and then I found out that it's actually OK in some circumstances. Can you guide me somewhere? <<

The RegisterRequiresPostBack article I mentioned explains the gist of it. If you want to use the page and control model, certain things have to be known across postbacks. Thats the way it is. It isn't like its just the way it was implemented -- no, it couldn't be implemented differently without quirks and bugs creeping in. For a checkbox, as mentioned in that article, it's due to a flaw (IMO) in how checkboxes are handled by browsers during posts.

I suggest you look at the MVC framework. Sounds right up your alley. There's no ViewState there.

weblogs.asp.net/.../search.aspx

# re: TRULY Understanding ViewState

Tuesday, January 22, 2008 4:50 PM by InfinitiesLoop

You didnt understand what I mean about the accordian. I know there are nice CSS ways of creating menus. But it's got nothing to do with my point :)

# Complex Code Behinds -> Passive View -> MVC

Tuesday, January 22, 2008 10:31 PM by DotNet

I&#39;ve been wondering... How does the typical web developer/team accomplish a n-tiered architecture

# re: TRULY Understanding ViewState

Wednesday, January 23, 2008 5:24 AM by Jakub Anderwald

Thanks for all the help and patience.

It might be I'm making unnecessary noise about some things, but the idea of sending information to / from user to make my application work properly gives me the creeps.

I will give it more read, maybe I'll find some sense in it.

# ViewState property code snippet

Thursday, January 24, 2008 3:25 PM by LavaBlast Software Blog

ViewState property code snippet

# re: TRULY Understanding ViewState

Friday, February 08, 2008 3:48 AM by Arun

Hi,

Excellent article... Now i understood wat all rubbish things i did in my previous projects... Ur examples were too good especially ur Grandmother worrying abt the states in US... Great work man... Keep it up...

# re: TRULY Understanding ViewState

Friday, February 08, 2008 9:15 AM by sanjeev

Hello,

I have a dropdownlist which i am getting filled using AJAX.

now the problem is that at the time of pageload and when the postback of the page occurs, the list gets empty and on clicking of a button only it gets filled again.

how can i maintain the viewstate of this list and how can i have the list populated at the page load by the deafult options.

thanks for your help.

sanjeev

http://mindgrillq.blogspot.com

# re: TRULY Understanding ViewState

Tuesday, February 12, 2008 1:55 PM by InfinitiesLoop

sanjeev -- changes to the page client side are going to be lost when the page refreshes. Thats the way it is. It isn't ViewState's job to remember client-side changes to non-form elements. DDL is a form element, but only its selected value is posted by the browser, not its entire list.

You'll have to store the items in a hidden field and use it to repopulate the list when the page reloads. Or just reload it automatically. That or don't do it client side. :)

# jacobslusser.com &raquo; Blog Archive &raquo; Quick and Dirty View of ViewState

Pingback from  jacobslusser.com  &raquo; Blog Archive   &raquo; Quick and Dirty View of ViewState

# Answers &laquo; .NET PATASALA&#8230;

Wednesday, February 20, 2008 1:24 AM by Answers « .NET PATASALA…

Pingback from  Answers &laquo; .NET PATASALA&#8230;

# TRULY Understanding ViewState, the comment index - Infinities Loop

Pingback from  TRULY Understanding ViewState, the comment index - Infinities Loop

# Know Your Friends Well, Know Your Enemies Better

Friday, February 22, 2008 3:24 AM by sfeldman.NET

Long time ago I had to deal with a case where the famous ViewState generated by WebForms was quiet heavy

# Truly Understanding Viewstate Mirrored

Friday, February 22, 2008 6:44 PM by Colin Bowern

Dave Reed and Trevor Morrison summarized the implementation challenges around the use of Viewstate .

# Application Software Building &raquo; Blog Archive &raquo; Understanding ViewState in ASP.NET

Pingback from  Application Software Building  &raquo; Blog Archive   &raquo; Understanding ViewState in ASP.NET

# re: TRULY Understanding ViewState

Thursday, March 06, 2008 10:52 AM by Troy

The option to set control properties in the OnPreInit event in order to avoid those values from being entered into the viewstate seems like a good idea.

weblogs.asp.net/.../master-page-and-preinit.aspx

This blog above points out that it will not work for pages that have a master page because the controls do not exist yet (in OnPreInit) if a master page is used.

He suggests this workaround, which does work.

MasterPage master = this.Master;  //add this line before any control properties are set in OnPreInit

I am wondering is this a good workaround or a hack?  Do you recommend it?

# re: TRULY Understanding ViewState

Friday, March 07, 2008 6:04 PM by InfinitiesLoop

Troy -- your comments about posted values and viewstate and all that are absolutely correct.

As for OnPreInit... the work around is kind of a bummer. It's not behavior I would count on existing in future releases of the framework, so use it with caution. Overall I'd say it would probably be best to find another way of implementing what you need, but if it works well for your scenario and you don't mind having to test it with future updates and possibly fix it, then so be it. Not that there's plans to change that behavior, but its certainly not a documented behavior which always makes it somewhat subject to  change.

# ASP.NET ViewState Explained

Friday, March 07, 2008 8:57 PM by blog.TroyFarrell.com

ASP.NET ViewState Explained

# re: TRULY Understanding ViewState

Wednesday, March 26, 2008 3:12 AM by Gazmend

you are so sick my friend

you should live in a movie

:)

# Managing State in ASP.NET - which bag to use and when &laquo; Enter the Tatrix

Pingback from  Managing State in ASP.NET - which bag to use and when &laquo; Enter the Tatrix

# ASP.NET State Management Patterns III: The ViewState

Sunday, April 13, 2008 1:14 PM by Code Heaven

Let&#39;s continue our work on ASP.NET state management patterns. The first part of this series (on Session

# re: TRULY Understanding ViewState

Wednesday, April 16, 2008 7:36 AM by Angela Law

Hey, I loved the article... And I am probably going to have to read it a couple of times to fully get the picture...

Here is a question fo ryou I thought maybe you could answer.

Can a program add *and* delete dynamically created usercontrols/controls that need viewstate to be enabled?

An example would be like google widgets or yahoo users home page. (these aren't .net apps mind you)

Many Thanks,

Angela

# re: TRULY Understanding ViewState

Wednesday, April 16, 2008 1:38 PM by InfinitiesLoop

Angela Law -- sure. But it depends on the process exactly if you even need to 'remove' them. It may be just be that you just 'don't add' the ones that should be 'removed', since you have to add all of them every request as it is.

# re: TRULY Understanding ViewState

Wednesday, April 16, 2008 10:19 PM by angelalaw

I can't seem to get this...

I read through your articles and I must say when it comes to .NET I am probably a toddler at it...

But I am trying to make a dashboard where a logged in user can custom create gadgets/widgets on the page.  Like google or yahoo.

Using the Update panel and a 3rd party widget control from Telerik called dock.

And I just don't see a way... I was trying to implement your thoughts...

But the trigger events for the updatepanel need to be loaded for each widget control in the Oninit area.  If I load them in the OnLoad area then it is not recognized and they don't fire.

However, if I load up in the OnInit area Session and Viewstate are not available so, I can't retrieve the order of the widgets loading nor the userid.

So, I am in a catch 22....

Anythoughts?  I been trying to resolve this for 2.5 weeks now... And I am baffled...

No one that i am working with understands viewstate unfortunately.  And the one solution someone is trying to implement is a clouge (you know fanagled)...that I think in the long run will still cause problems...

Any help would be greatly apprecaited!

Angela

# re: TRULY Understanding ViewState

Wednesday, April 16, 2008 10:22 PM by angelalaw

Oh, one other thing... I do need to remove them... For instance someone can have up to 30 choices to place on the dashboard page...However, they are limited to 7 allowed at one time

So they can add and delete and look at different widgets.  Which means, that someone could literally look at 30 widgets.  

And these widgets are using grid with ajax, charting tooks, dropdowns, ect....

Is it to ambish?

Thanks again I redo appreciate... i will being reading your articles again tommorrow to see what else I missed...

Angela

# re: TRULY Understanding ViewState

Wednesday, April 16, 2008 10:33 PM by InfinitiesLoop

Angela -- its really hard to say what you should do without more specifics. It sounds to me like you may be overthinking it. Just because they can look at 30 widgets doesn't mean there have to be 30 on the page and then you remove some. Unless I'm not understanding your scenario.

First thing I'd do if I were you is throw away the update panels. UpdatePanels do not equal instant greatness. You have to get the form working without them for there to be any hope of it working with them. Remove them, or turn off PartialRendering, and see how your page works then. If it works, great, then move on to adding in update panels. Trust me on this one. Perhaps that is one area you're getting confused with. If you have 30 things showing up on the page, it doesn't mean you have to remove them to get rid of them. Each post is a completely new request with completely new response. Removing one could be just as easy as just adding 29 of them this time instead of all of them. If you're talking about update panels that might confuse you because you think it needs to be removed somehow since there's this 'live' version of everything staying on the page after each post. Its not the right way to think about it. Each time there is a post, whether it is asynchronous or not, imagine the entire page just being thrown away completely and then rebuild from the response from the server. UpdatePanels do give you a way to update only one part of the page at a time, but its only an optimization for display purposes, nothing more! You still need to treat the postback like a regular one.

# re: TRULY Understanding ViewState

Thursday, April 17, 2008 12:31 AM by Angela Law

Hi, thanks so much for your thoughts... one of the very first things I did was remove the updatepanel and I am still having trouble getting the events to fire for these controls if they are not declared in the OnInit area.

As far as specifics... Imagine the following:

You have initial web page that all it has on it is a dropdown where you can select any of the 30 widgets you can put on that page.  Once the dropdown changes it fires the Onchange event for the dropdown and it then goes through and adds that widget to your page in a particular area.

Remember, you are limited 7 total out of the 30 you can select from.  

However, you have the ability to delete a widget and add a new one anytime you want.  A widget being a usercontrol, which can contain dropdowns, calendars, charts, grids and should be able to ajax back to get information.

www.naturallyspiritual.com/.../widgets.jpg

that is my personal site... But it gives an example of a UI design my company is expecting me to produce.

Add widgets is really a dropdown that has a list of widgets that can be added dynamically through ajax.

I am supposed to be able to have a prototype by May 1st.  In otherwords, I need to be able to say with confidence yes we can do this with this technology and see I made it work...or *can* make it work...

And no one I am working with including myself knows what is possible.

Any help or advice you could offer would be greatly appreciated ;)

Angela

Right now I don't feel so confident.  And am considering a 2 page alternative.  As in the select what they want on one page (whether selecting or deselecting) and then goto the dashboard page to have it rendered dynamically yet static that it won't change the # of controls on the page.

# re: TRULY Understanding ViewState

Thursday, April 17, 2008 3:46 AM by InfinitiesLoop

Angela -- here's one way I see it working. The dropdown list firing the onchange event is a postback assuming you are talking about the DropDownList.SelectedIndexChanged event. Before that event actually fires in the postback, you'll be going through Init and Load. ViewState is available in Load. From there you will need to recreate all the controls the user has added on previous postbacks. How you determine that could be from a database or it could be from viewstate, maybe session, such as through an arraylist of widget ids or something (not the widget itself mind you, just whatever you need to determine which one in the list it is). After Load, and before PreRender, is where the SelectedIndexChanged event from the dropdown will fire. In the handler, you will determine which is to be added, add it, and also update the store you are using to remember which the user has added for the benefit of the next postback. When you load a widget dynamically you should be sure to give it an ID that is specific for that type of widget to avoid a shifting ID problem. For example, each time you load an added widget, increment a counter that is stored in ViewState, and give it the id="widget" + counter, then store the ID you assigned it as part of the ViewState or Session store you use to recreate them on postbacks, so that you be sure to give each one the same ID it had last time. When removing a widget, not only do you remove the control from the page, you also remove its corresponding entry in the store so that it simply isn't recreated on the next postback.

# 今天学习了一点viewstate:-)

Friday, April 18, 2008 9:40 AM by qdboyqf

viewstate

# ASP.Net View State &laquo; Steve Godbold

Monday, April 21, 2008 1:30 AM by ASP.Net View State « Steve Godbold

Pingback from  ASP.Net View State &laquo; Steve Godbold

# Dynamic controls, lost after postback

Monday, April 21, 2008 9:41 PM by The3Factory

Dynamic controls, lost after postback

# re: TRULY Understanding ViewState

Thursday, April 24, 2008 12:31 PM by wcygan

This is great stuff, thanks. One more AJAX question: I understand that the ViewState won't/shouldn't know anything that is done on the client side if the page is refreshed. But when a client-side process updates a control like a drop down list, why doesn't the ViewState handle the value once the whole page is posted back?

I have a couple of cascading drop downs (car make and model) that use AJAX. A user selects a value for one or both as part of a query. Once they have entered selection criteria in a number of fields, they submit the page and see the results. If they click the back button to alter the query, the non-AJAX fields are still populated but the drop down lists have lost their values. The controls have "Enable ViewState" properties, but this doesn't seem to work.

After all, if I am typing a value in a field, I am a client-side process, but once I submit the form, the data is sent to the server-side where the ViewState should be able to handle it.

Do you have any suggestions?

Thanks, Walt

# re: TRULY Understanding ViewState

Thursday, April 24, 2008 1:21 PM by InfinitiesLoop

Walt, the list of options that appear within a dropdown are not part of the data the browser sends to the server when it posts. Only the selected value is. Just like say the width of a textbox isn't sent to the server, only its value. So there's no way the server can know about changes to the dropdown client side unless you specifically code for it (such as by using hidden fields). You can think of it in a traditional windows forms app, leaving the page and coming back is like restarting the windows app, it's going to lose changes to its initial state that were done programmatically unless you purposely saved that state somewhere and actively reconstruct it.

# re: TRULY Understanding ViewState

Sunday, April 27, 2008 3:06 AM by Pradeep

Great Article!!!!!

I have a question though...How can i calculate viewstate size.

specially of the ones added by the developer on the page.

eg:Viewstate["somekey"]="Somevalue";

Can you please help in this regard.

# re: TRULY Understanding ViewState

Sunday, April 27, 2008 5:25 AM by InfinitiesLoop

Pradeep -- the simplest way would probably be to just look at the page source, copy it into notepad, save it, and look at the file properties :) There are viewstate decoding tools out there too that would be helpful, just search for viewstate decoder and I'm sure you'll find one or two. Enabling asp.net trace also shows you viewstate size broken down by control.

# decodificando el ViewState... para verle hasta las venas

Friday, May 02, 2008 9:40 PM by SergioTarrillo's RichWeblog

El tema de ViewState es tema muy triado, pero no he tenido la oportunidad de comentarlo y entenderlo

# re: TRULY Understanding ViewState

Monday, May 05, 2008 7:19 AM by durden81

Impressive article.. you are the best blogger about ASP.NET on the Internet.

ScottGu should keep reading your blogs until he (hopefully) gets it and understand how it's done ;)

# re: TRULY Understanding ViewState

Monday, May 05, 2008 7:44 AM by stan

I really enjoyed reading your article, it was my first I read to get a clue on Viewstate and I found it very easy to comprehend. But how do you keep at least your own Viewstate THAT short? It's some kind of miracle, I guess.

nice work! keep it on :-)

# re: TRULY Understanding ViewState

Thursday, May 08, 2008 12:54 PM by Mark

Great article!

After reading it I feel "dirty" about the waste of resources that my current project is doing (now that I know it!).. so I am thinking of doing a major clean-up in my web-application..

At the moment it suffers a big size of USELESS viewstate... as a lot of useless data is there. This affects every page. (but I am persisting viewstate in Cache objects and not on the page.. which is the quickest site-wide fix for this problem by the way ;) )

The whole site is full of custom usercontrols and the data is defined in Page_Init or Page_Load or Page_Render (what a mess).

Ok would the following be the right way to proceed?

1. Put ALL the code that binds the data of the user controls and Page controls during the first load in the overriden DataBind().

2. Delete ALL calls to DataBind() of any sub controls from all UserControls and pages.

3. in every Page_PreInit of the page controls call DataBind() and so Asp.net will recursively do the right work.

4. live happily ever after

It would be great to have a quick reply with suggestions asap.. before I do something wrong :-s.

Thanks!

# re: TRULY Understanding ViewState

Thursday, May 08, 2008 12:57 PM by Mark

ah yes, also it's not clear to me this:

If I call MyUserControl.DataBind() in page_prerender of the page, and there are <%# tags in the user control... will this go into the viewstate or not?

# re: TRULY Understanding ViewState

Thursday, May 08, 2008 1:24 PM by InfinitiesLoop

Mark -- don't do steps 1-3, just skip directly to 4 :)

Seriously, your steps don't sound right at all, sorry. What you need to do really depends on, well, everything that is going on. I can't tell you that you should "delete all calls to databind of any sub controls" because theres lots of times where you do need to do that. The only way to improve your viewstate usage without breaking everything is to really look at it and understand it on a case-by-case basis. Start with one page, and just one aspect of that page.

And yes, PreRender is before SaveViewState, so binding from there still dirties viewstate.

# re: TRULY Understanding ViewState

Thursday, May 08, 2008 4:14 PM by Mark

Good idea, step 4 it is ;)

But seriously, I read the article again and I found where the problems of my confusion comes from..

1) In "3. Persisting cheap data" you say that by overriding OnInit and databinding a dropdown inside it, the ListItems are not persisted in the ViewState. Well which OnInit do you have to override for this to happen?

In my page I have a dropdown in a UserControl and I overrode the OnInit of the usercontrol and I don't touch it afterwards but data is STILL persisted in ViewState anyway.. (I use viewstate decoder to check this).

And also this behaviour seems perfectly logical to me: first TrackViewState() is called in the dropdown and then OnInit of the parent UserControl is executed, and so binding the dropdown there is too late.

What is wrong in this reasoning?

2) And then another confusion is with the fact that in "5. Initializing dynamically created controls programmatically" you say that with this method the dynamic control is like one that is fully declaraed in the aspx page and you only need to populate it the first time... if this is the case why don't you populate the control once also in case "3 3. Persisting cheap data"... I mean it's probably even cheaper and faster retrieving it just for the first page load...

I'm most probably wrong somewhere.. but can't find where ... any idea? shall I start look for a new profession?

# re: TRULY Understanding ViewState

Thursday, May 08, 2008 4:29 PM by Mark

Ok I have now seen that there is EnableViewState="false" set in the example "3. Persisting cheap data"... sorry I didn't notice this before.

So the reason for point 1 is now clear to me :)

# re: TRULY Understanding ViewState

Thursday, May 08, 2008 5:17 PM by InfinitiesLoop

Mark --

1) you answered yourself :)

2) I think you missed the point of 'cheap' data. The data is cheap to get, so why not get it every request? In regard to getting the data, yes its cheaper to get it only once. But then the data is persisted in viewstate! What's cheaper, getting the data every time, or getting the data once and then allowing viewstate to maintain it for you?

In example 5, I don't think I ever said "and you only need to populate it the first time". I wouldn't every say that in general. It depends on your needs whether you need to every time or not.

Try not to come up with "truths" like "always do this...". The trick is to understand how it works so you KNOW what you should do, not just follow a "menu" of tricks, you're just as likely to be doing something wrong that way...

# re: TRULY Understanding ViewState

Saturday, May 10, 2008 12:33 PM by kumaram

I am having 20 user controls within a multiview and i am able to show the user selected Activeview, but the Page_Load is called for all of the user controls.

so I have restricted the user to process the code in page_load for the Activeview . But the application memory grows for every action within the application.How to handle the memory leak in this scenario.

I do not know where to start to fix the issue.Please help.

# re: TRULY Understanding ViewState

Saturday, May 10, 2008 4:49 PM by InfinitiesLoop

kumaram -- just having a multiview wont cause a memory leak. If you have one, which you don't necessarily have, its probably due to whatever the controls are doing such as database access, not closing the connection, storing things in cache, etc. I say you may not have a leak because just the fact the memory usage increases doesn't mean there's a leak. The growth could be unrelated to you controls, or it could just be that garbage collection hasn't occurred yet. If you're doing the right thing in the controls (disposing of external resources like window handles or db connections) then you probably have nothing to worry about.

# re: TRULY Understanding ViewState

Thursday, May 15, 2008 11:40 AM by .net freshman

Hi,

I'm having this weird problem.   I have a custom user control with its own custom validator.  I draw instances of it on a page dynamically.

The problem is that if I draw them in the oninit phase of the page, the validate event for the custom control fires before the validate event of the page and so in the Page's validate event I can determine whether everything was ok via Page.IsValid.

However, if I draw them on the OnLoad event of the page, the validate of the custom control fires after the page's validate event, and that just doens't work for me!

I want to be able to draw them in the onload.  Is there a way I can get the control's validate to fire before the page's?

Also another question:  You mentioned early on in the article that posted values aren't maintained via Viewstate.  Then how are they maintained?  If I draw my dynamic controls in the oninit or onload, then they are able to persist, but if I draw them after those events, then they don't persist values on postback.  What gives?

# re: TRULY Understanding ViewState

Monday, May 19, 2008 5:32 AM by brauliod

Pretty good article !!! superb !!!

Do you think is worthy to update it for 2.0 and StatControl?

# re: TRULY Understanding ViewState

Thursday, May 22, 2008 4:37 AM by Cosmin

thank you so much or the article. i even found exactly what i was looking for.

i have a problem though. i have a dropdownlist which is bound to a object data source. i have disabled the viewstate for all the page. i managed to databind the dropdown correctly and all works fine. it's set to autopostback=true. problem is when trying to capture the "on selected index changed". the method associated is hit everytime, except when i select the first item in the list.

i read a bit in the msdn and it says about this control that it shoul have viewstate enabled: "A list control must persist some values between posts to the server for this event to work correctly. Be sure that view state is enabled for the list control."

is there a way to capture the "on selected index changed" everytime without using viewstate?

# re: TRULY Understanding ViewState

Saturday, May 24, 2008 11:02 AM by Jo&#227;o Rollo de S&#225;

Whow im kind a new in ASP .NET 2 but Understanting, the insights of how Viewstate Works is truly a Gurus thing.

Thanks a lot For this journey into Viewstate Internals, and its 5 Rules Of Thumb!

Cheers from Portugal

# re: TRULY Understanding ViewState

Monday, May 26, 2008 11:01 AM by Martin

Good Article.

I appreciated the humour. If it had been a completely dry article I would probably have never persevered to the end!

# decodificando el ViewState... para verle hasta las venas

Friday, June 06, 2008 1:45 AM by ASP.NET Espanol Blogs

El tema de ViewState es tema muy triado, pero no he tenido la oportunidad de comentarlo y entenderlo

# Flyvergrillen &raquo; Blog Archive &raquo; ViewState optimering

Monday, June 16, 2008 11:38 AM by Flyvergrillen » Blog Archive » ViewState optimering

Pingback from  Flyvergrillen  &raquo; Blog Archive   &raquo; ViewState optimering

# re: TRULY Understanding ViewState

Thursday, June 19, 2008 3:56 PM by Sadia

I just read your article and has been very helpful in clearing up the unexplained fog of viewstate. I have a question related to viewstate and callbacks. I understand how I can refresh the controls on the page by using

_theFormPostData = ''; and then WebForm_InitCallback();

Here is my situation: I have multiple callbacks on a page. I have a custom object that contains some significant information that is used from one call back into the other.

the object gets initialized at page load. I retrieve the pageload value at callback1... callback1 sets a new value to the same key in viewstate and callback2 is supposed to retrieve the callback1 value.

But this is what happens when I retrieve the value from the view it is always the value that was set in the page load. How can I make the viewstate retain the value from callback to callback.

Thanks,

Sadia

# re: TRULY Understanding ViewState

Thursday, June 19, 2008 4:05 PM by curtisdehaven

Hi Dave,

Thanks for education on ViewState - very interesting.  The basic rule of thumb I'm getting out of this is that controls that get populated inside the "if(!IsPostBack)" of Page_Load should use the ViewState for successive posts.  But controls that get populated on the "else" or every call should leave the ViewState alone.  In my current application, the controls inside the "if(!IsPostBack)" are dropdowns that contain somewhat dynamic data from a database - so i'm sacrificing viewstate in exchange for minimal trips to the database. (while the data is dynamic in nature, its static enough to take a snapshot for the life of the session.)

Thanks again!

Curt -- PhillyPa

# re: TRULY Understanding ViewState

Thursday, June 19, 2008 4:23 PM by InfinitiesLoop

Sadia -- Callbacks do not update viewstate that resulted from the post. To do that you've have to switch to using an UpdatePanel, which maintains everything.

# re: TRULY Understanding ViewState

Friday, June 20, 2008 9:58 AM by Sadia

If "Callbacks do not update viewstate that resulted from the post", then at what stage of the page life cycle should I initizalize the viewstate with the required object, so I can update it in the callback and it will maintain the view state.

I would love to use update panel, but the team I am working is somewhat anti update panel.

Thank you for your help.

# re: TRULY Understanding ViewState

Friday, June 20, 2008 1:19 PM by InfinitiesLoop

Sadia -- you simply can't with callbacks. ViewState is posted to the server when a callback occurs, but the new viewstate from the response does not get send back to the client. Therefore each callback you make will always be with the same viewstate you had when the page first loaded.

UpdatePanel does maintain viewstate round trip. Why are they anti-updatepanel? A callback that also updates viewstate (if one existed) is actually pretty much exactly what update panels do. You can't want what update panel does but still not like update panels :)

What you will have to do send the data you need back in the callback result, store it in a hidden field or a javascript variable, and just keep it going back and forth yourself, without relying on viewstate to do it for you automatically.

# Must-read article for ASP.NET Dev &laquo; Nguyenminhdung&#8217;s Weblog

Pingback from  Must-read article for ASP.NET Dev &laquo; Nguyenminhdung&#8217;s Weblog

# Truly Understanding ViewState

Wednesday, June 25, 2008 7:58 PM by U R my.Net

# ViewState woes? &laquo; hashName

Friday, June 27, 2008 7:10 AM by ViewState woes? « hashName

Pingback from  ViewState woes? &laquo; hashName

# | SQL Server Feeds

Tuesday, July 22, 2008 9:24 PM by | SQL Server Feeds

Pingback from  | SQL Server Feeds

# Using client templates, part 1

Thursday, July 31, 2008 3:35 AM by Community Blogs

Last week, we shipped the first preview for the Ajax work we&#39;re doing in ASP.NET 4.0 under the simple

# re: TRULY Understanding ViewState

Thursday, July 31, 2008 10:04 AM by Elwap

I think one of the major confusions for developers is not understanding that "input" controls such as textboxes, checkboxes and radiobuttons can use both viewstate or the IPostbackData handler to maintain/restore their values.

Even if an "input" controls viewstate is off during a postback, because these controls implement the IPostbackData interface they restore their "posted" values from the form to the input control.

Check it out for yourself by switching off viewstate on input controls (e.g. a textbox), causing a postback, and looping over the request.form using a foreach loop in the code behind.

Notice the input values still get submitted and restored?! And that's the key to what happens when viewstate is off for an input control. When you do a simple postback - it uses this request.form value to repopulate the input controls.

However, this doesn't mean that input control properties (such as the "text" property) are not stored in viewstate - because they are. Remember that "Text" is "property" of a textbox (and remember viewstate stores "properties" of controls) - therefore the textbox "Text" property IS stored in viewstate.

In my first example described a very simple postback to repopulate the controls.

Here's and example of when an input control (a textbox) uses viewstate to maintain it's "Text" property.

1. Create a aspx page with two panels.

2. Panel1 has a textbox and a button (that causes postback) and the panel1 is visible.

3. Panel2 has a button only (causes postback) and is invisible.

4. In the codebehind, handle the Button OnClick event for Panel1  and by making Panel2 visible and Panel1 invisible.

5. Handle the OnClick event of the button in Panel2 by making Panel1 visible and Panel2 invisible.

6. Now, load the page and add some text into the textbox of Panel1 and cause a postback - panel2 appears with a button.

7. Now click on the button in Panel2 and make Panel1 visible. Notice that the textbox maintained the value you initially submitted? This is because it used viewstate to store the "Text" property of the textbox.

8. Now switch off viewstate on the textbox and try the same process again. Notice that the textbox loses it's value when you return to panel1?! Proving that input controls do use viewstate to store their properties as well as using the IPostbackData interface to reload their values on postback.

Hope this helps......

# re: TRULY Understanding ViewState

Thursday, September 04, 2008 10:09 PM by y2kstephen

excellent article

thx a lot !

# Using client templates, part 1 | Programming Archive

Thursday, September 11, 2008 9:02 AM by Using client templates, part 1 | Programming Archive

Pingback from  Using client templates, part 1 | Programming Archive

# re: TRULY Understanding ViewState

Sunday, September 14, 2008 11:06 PM by ASPeon (I just does what I'm told)

I've been at this for hours until I finally found your article - working now - thanks!

# re: TRULY Understanding ViewState

Tuesday, September 16, 2008 9:38 AM by Mark Wright

Thanks for a great article.  I wasted a day and half trying to get ViewState to make my coffee.  If only I'd read your article first!

# re: TRULY Understanding ViewState

Wednesday, September 17, 2008 11:57 AM by KSK

Awesome article! thanks for putting it altogether!. I never understood Viewstate this clearly until I read this article.

However, I am facing a weird problem with not using Viewstate for a datalist, which I have tried to outline below. Any feedback will be highly appreciated!

I have a Datalist with Edit & Delete capabilities, so I have the OnEditCommand, OnDeleteCommand, OnUpdateCommand & OnCancelCommand event handlers defined on this datalist.

Note: the Edit & Delete buttons are inside the ItemTemplate & Update & Cancel buttons are inside the EditItemTemplate

If I have the Viewstate enabled on the datalist & have the databind() called in the condition if (!IsPostBack), everything works fine.

But since I do not want the data in the datalist to be carried around in the Viewstate, I do the following:

1) Disable Viewstate on the datalist

2) Call the databind() without the if (!IsPostBack) condition - i.e. rebind datalist on each request

The behavior now is as follows:

1) On pressing Delete button, the delete command execute successfully (OnDeleteCommand event fires successfully) - row gets deleted.

2) On pressing the Edit button, the Edit command execute successfully (OnEditCommand event fires successfully) - row is displayed in Editable mode

3) Once in Editable mode, if I press Cancel button, this event also fires successfully & Editable mode disappears

4) But on pressing the "Update" button, the OnUpdateCommand event does not fire at all ! (record changes do not get updated).

What would be the reason that all other events fire except the UpdateCommand?

Note: I also have a "View Details" button defined in the ItemTemplate - which takes the user to another page for viewing further details of the current item. For this I have an OnItemCommand event handler also defined for the datalist. This event also executes fine. It is just the UpdateCommand not firing sucessfully.

# re: TRULY Understanding ViewState

Wednesday, September 17, 2008 3:14 PM by InfinitiesLoop

KSK -- the DataList is going to revert to its original state each request. That means it wont remember which row was being edited.

Take this advice -- put a regular button somewhere on your page (outside of the datalist). It wont do anything but cause a postback. Whenever you are developing a page, especially if you are turning off viewstate, you should test what happens if all you do is push that button. Currently, after editing a row, then clicking that button, you will see the datalist return to a non-edit status. So you arent getting the update command because the datalist isnt even in an edit state! To keep it in an edit state, you have to set the EditItemIndex on every request, it isn't going to remember it for you since you disabled viewstate.

# re: TRULY Understanding ViewState

Thursday, September 18, 2008 1:22 PM by NTH

Yes! setting the EditItemIndex on everyrequest did the trick!

Here is how I did it (for others like me who come looking for a solution:=):

1) I stored the EditItemIndex value in a hiddenfield (defined outside the datalist - so that it is in viewstate). The hiddenfield will have no initial value

2) In OnEditCommand event handler:

datalist.edititemlndex = e.item.itemindex;

hiddenfield.Value = e.item.itemindex.ToString();

DoDatabind();

3) In page_load:

if (!IsPostBack)

    DoDatabind();

else

{

   if (hiddenfield.Value != "")

   {

          datalist.edititemlndex = Convert.ToInt32(hiddenfield.Value);

          DoDatabind();

   }

   else

         DoDatabind();

}

4) In OnUpdateCommand event handler:

DoUpdate();

datalist.edititemlndex = -1;

hiddenfield.Value = ""; // this is required to get out of editmode on postback

DoDatabind();

That's it!

I spent 1.5 days trying to research this issue - I wish I had come across this article earlier!. Thanks for coming to my rescue:=)

# “视图状态损坏”的困扰

Sunday, September 28, 2008 2:35 AM by Shiny Zhu

如果你在调试或访问ASP.NET页面的时候遇到

# Estado de Visualiza????o em ASP.NET &laquo; Oooops, criei um Blog

Pingback from  Estado de Visualiza????o em ASP.NET &laquo; Oooops, criei um Blog

# Dynamically Created Controls in ASP.NET | Mrunal Brahmbhatt

Pingback from  Dynamically Created Controls in ASP.NET | Mrunal Brahmbhatt

# TRULY UNDERSTANDING VIEWSTATE | Mrunal Brahmbhatt

Friday, October 17, 2008 4:19 PM by TRULY UNDERSTANDING VIEWSTATE | Mrunal Brahmbhatt

Pingback from  TRULY UNDERSTANDING VIEWSTATE | Mrunal Brahmbhatt

# Viewstate

Saturday, October 18, 2008 4:33 PM by Nathan Allen-Wagner

Viewstate

# re: TRULY Understanding ViewState

Tuesday, October 21, 2008 10:00 PM by Craig W

Excellent article. It really helped clarify any viewstate questions I had and your examples were good at re-enforcing everything and giving me a solid understanding of things I may not have caught right away.

Thank you.

# re: TRULY Understanding ViewState

Friday, October 24, 2008 9:59 AM by Alex

Thanks for this wonderful article.

I hope you're still answering questions.

I have a CompositeControl that load another CompositeControl, which in turn loads several standard WebControls.

I have come across a problem where ViewState seems to be overriding programmatic declaration of control values.

-- ASPX.CS --

OnInit

{

   CompositeControl myControl = Activator.CreateInstance(Assembly.Load("App_Code").GetType("MyControl"));

   MainPanel.Controls.Add((Control)pageControl);

}

-- END ASPX.CS --

-- MyControl --

OnInit

{

   firstName = new TextBoxBase();

}

CreateChildControls()

{

   firstName.TextBox.Text = "Shouldn't Be Able To Override This.";

   Controls.Add(firstName);

}

-- END MyControl --

-- TextBoxBase --

private TextBox _textBox;

public TextBoxBase()

{

   _textBox = new TextBox();

}

public TextBox TextBox

{

   get { return _textBox; }

   set {_textBox = value; }

}

CreateChildControls()

{

   textBox.Text = "Can't override 2";

   textBox.EnableViewState = true;

   Controls.Add(textBox);

   textBox.Text = "Can't override 3!";

}

-- END TextBoxBase --

The problem is that when the FirstName field is changed on the page and is posted back, it _always_ shows the text entered in the field, rather than the text declared programmatically.

Shouldn't my TextBox.Text code override ViewState?

I thought that's why I'd use !Page.IsPostBack around these lines if I didn't want them to have any affect, but as it stands, they have no affect under any circumstance.

Thanks again!

# re: TRULY Understanding ViewState

Friday, October 24, 2008 3:33 PM by alexwalker

I would find it useful if you would add an addendum covering how some controls look like they're using ViewState when they're really not.

support.microsoft.com

and

ControlState

# getElementById mal anders - Seite 2 - jswelt - Forum (Javascript, PHP, MySQL, AJAX, Webdesign)

Pingback from  getElementById mal anders - Seite 2 - jswelt - Forum (Javascript, PHP, MySQL, AJAX, Webdesign)

# Mike Mason &raquo; Compressing Viewstate

Tuesday, November 04, 2008 6:07 PM by Mike Mason » Compressing Viewstate

Pingback from  Mike Mason &raquo; Compressing Viewstate

# Compressing Viewstate

Saturday, November 08, 2008 11:10 AM by Blog of Developer Mikkel Ovesen

Compressing Viewstate

# re: TRULY Understanding ViewState

Tuesday, November 11, 2008 4:20 AM by srinivas

Thanks for your clear explain about viewstate .

# re: TRULY Understanding ViewState

Tuesday, November 11, 2008 9:37 AM by CL

Awesome article, finally I can understand write more efficient web form with less VIEWSTATE

# Thoughts on Team

Monday, November 17, 2008 12:48 AM by BlackInkBottle's Ink

(1) Recently comtemplating on team allocation in response to sometimes unexpected staff turnover. I hold

# re: TRULY Understanding ViewState

Thursday, November 20, 2008 4:21 AM by Frog

thanks!

# A Better way to Deal with Viewstate &laquo; The Old Sewing Factory

Pingback from  A Better way to Deal with Viewstate &laquo; The Old Sewing Factory

# re: TRULY Understanding ViewState

Wednesday, November 26, 2008 2:54 AM by Laredo

Hi,

Awesome article. I'm looking for an elagant way to do the following:

I nead to dynamically generate a control depending on the result of a control post pack(let's say a dropdownlist)

Here is my work around method:

protected void Page_Init(object sender, EventArgs e)

   {

       int Mode = Convert.ToInt32(Page.Request["Mode"] ?? "0");

       if (Mode == 1)

# re: TRULY Understanding ViewState

Wednesday, November 26, 2008 3:09 AM by Laredo

Awesome article.

I'm looking for an elagant way to do the following:

I nead to dynamically generate a control depending on the result of a control postback(let's say a dropdownlist)

Here is my work around method:

protected void Page_Init(object sender, EventArgs e)

   {

       //Page init where I would create a control depending

       //on the dropdownlist selection

       int Mode = Convert.ToInt32(Page.Request["Mode"] ?? "0");

       if (Mode == 1)

       {

              //Create Control 1

        }

        else(Mode == 2)

        {

         }

   }

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)

   {

       Server.Transfer("./DetailView.aspx?Mode=" +     DropDownList1.SelectedValue);

   }

Ideally I'd prefer to just use the DropDownList1.SelectedValue.

As I can only use the DropDownList1.SelectedValue in the Onload event I'd have to create my controls in this event as well. This of course would mean that the viewstate would be incorrect for the generated controls. How would you approach this problem. Is this the best solution?

# re: TRULY Understanding ViewState

Monday, December 01, 2008 3:49 PM by InfinitiesLoop

Laredo -- You should look at my article on understanding dynamic controls, and specifically the one 'by example' with an attached project that demonstrates it.

# re: TRULY Understanding ViewState

Wednesday, December 10, 2008 5:28 PM by InfinitiesLoop

Alex -- been so long you probably wont see my reply, but here it is anyway. When you create a control dynamically, it hasnt loaded its viewstate until you add it to the control tree. So you are setting the value and then viewstate loads, changing the value. In this case it is also loading postback data, which further reloads the value. I'm not sure why you wouldnt want a textbox to keep the user entered value on a postback, but you will need to change the value after it has already loaded postback data in that case. For a control added dynamically from OnLoad, that would be in PreRender. If added in OnInit, then OnLoad would work. This behavior by the way exactly mimics what you get with a statically declared control and should be what you would expect -- the declared value is set on the control's property every request, too. Just that it is done for you automatically so you don't think of it that way.

# re: TRULY Understanding ViewState

Friday, December 12, 2008 2:40 AM by debajdu

Thanks for this great article. It really helped me to understand viewstate lot better :)

just needed to clarify one thing

I did a test to clarify my understandings on the viewstate. I created a button in the OnInit method during !IsPostBack and a Label control during the PostBack. I assigned a text to the Button control. When I clicked on the Button, the button control disappeared as expected but I was suprised to see the Label control taking the text of the button. if the viestate uses ID's to reload the state data, then how is this happening?

# re: TRULY Understanding ViewState

Wednesday, December 24, 2008 1:53 PM by pmatsinopoulos

Firstly THANKS for your article. I believe it is VERY GOOD.

Meanwhile, though I believe that I have understood what you have written, I cannot really understand why when changing pages in a gridview the gridview brings the original result set and not the one that I have dynamically defined.

In Detail:

Summary: I have a gridview bound to an sql data source. The gridview has paging enabled. I change the SelectCommand Property of the sql data source dynamically as result of pressing a button. Then I press the next page button that appears at the bottom of the grid view and the grid view repopulates with the initial SelectCommand and not the new that I set dynamically. Why does this happen? Since both sql data source and datagridview have EnableViewState set to TRUE, I would expect that between postbacks, the SelectCommand retains any changes that I dynamically do to its value.

In order to demonstrate my problem, I have create a simple test.aspx page. Here is the code:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test.aspx.vb" Inherits="test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/.../xhtml1-transitional.dtd">

<html xmlns="www.w3.org/.../xhtml" >

<head runat="server">

<title>Untitled Page</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<asp:SqlDataSource ID="sqlds1" runat="server"

ConnectionString="<%$ ConnectionStrings:backendDatabase1 %>"

ProviderName="<%$ ConnectionStrings:backendDatabase1.ProviderName %>"

SelectCommand="select 1 as id union select 2 as id union select 3 as id union select 4 as id union select 5 as id"

EnableViewState="True"></asp:SqlDataSource>

<asp:GridView ID="gv1" runat="server" AllowPaging="True" EnableViewState="True" PageSize="2"

DataSourceID="sqlds1">

<Columns>

<asp:BoundField DataField="ID" />

</Columns>

</asp:GridView>

<asp:Button ID="btnChangeSelect" runat="Server" UseSubmitBehavior="True" Text="ChangeSelect" />

</div>

</form>

</body>

</html>

As you can see, when you first load the page, the gridview has 3 pages, with 5 items in total, 2 items 1st page, 2 items 2nd page and 1 item last page.

When somebody presses the 'ChangeSelect' button, the code that is executed is the following:

Protected Sub btnChangeSelect_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnChangeSelect.Click

 Me.sqlds1.SelectCommand = "select 1 as id union select 2 as id union select 3 as id"

End Sub

When the page returns/reloads after the pressing of the button, everything is as expected. The gridview contains only 3 items and it displays 2 pages. The 1st page is shown.

Then, immediately after that, I press the page number "2" to hopefully see the item with id "3", the last in the current select result.

UNFORTUNATELY, I see the original select result with all 5 items appearing again, and 3 pages instead of 2. !!!! WHY?

Looking forward to your help.

pmatsinopoulos

# re: TRULY Understanding ViewState

Monday, December 29, 2008 12:25 PM by InfinitiesLoop

pmatsinopoulos -- because the command itself is not saved in viewstate like most other properties are. Only the parameters to the command are viewstate managed.

Why that is? You really should not put such a thing in viewstate. You have to consider anything that is viewstate managed to be controllable by the end user, because unless you are encrypting your viewstate it can be manipulated -- and then even if it is encrypted, its better not to put stuff in viewstate that you dont need to.

Its also probably wasteful to put the command in viewstate. You probably only have a small set of possible commands, right? Or maybe there's a large set of possible commands, but they only vary in some small way, correct? Better than to put only the data which you will need to reconstruct the command in viewstate, then do so dynamically, than to just put the entire thing in viewstate. That limits the realm of possibility if someone where to gain control over viewstate, they would still be limited to the commands you build from the data (which you would be ensuring are within acceptable ranges).

# re: TRULY Understanding ViewState

Monday, December 29, 2008 12:51 PM by jshallard

A really great article, thank you for taking the time to write it - it must have taken a while.

I wanted to add a related piece of info to the conversation - apologies if it is covered elsewhere and I overlooked it.  I would be interested in any feedback/comments you have on this.

TURNING VIEWSTATE OFF - PARTICULARLY WITH DATABOUND CONTROLS.

This is something I have been wrestling with recently.  I'll keep the background to a minimum as most of it is already in this article.

DATABOUND CONTROLS:

- Viewstate quickly becomes massive

- If Viewstate is turned off, COMMAND EVENTS ONLY FIRE IF THE WHOLE CONTROL IS RE-DATABOUND prior to the event phase of the page lifecycle.  The reason for this is that the CommandName and the CommandArgument are not posted to the server.  The EVENT TARGET is THE ONLY INFORMATION THAT IS POSTED  (i.e. the UniqueID of the button that was clicked). The whole databound controls object tree has to be recreated to allow the framework to retrieve the ComandName and the ComandArgument.  This creates two significant problems. Say we have a table of items with a delete link button like so:

<asp:LinkButton ID="Select" runat="server" CommandName="Delete" CommandArgument='<%#Eval("Name")%>'><%#Eval("ID")%></asp:LinkButton>

-- The user clicks on the delete button for the 5th item in the list.  However, by the time they have done this, another user (logged in on a different computer) may have deleted item number 1.  Thus, when the data is fetched again (to allow the events to fire) the 5th user in the list is not the same - and the wrong item could end up getting deleted!

-- If an item is getting deleted (or edited), the data will almost certainly need to be re-fetched and re-databound AFTER the event has been processed.  Thus, it seems incredibly inefficient for ASP.Net to require a full datafetch and databind just to get two small pieces of information (the CommandName and the CommandArgument of the button clicked), when this will need to occur again after the event.  However, this is in fact the situation.  The only obvious alternative is to keep viewstate on - which for a databound control of any size quickly gets very large.

THERE IS A SOLUTION (I THINK)!

Upon examining the single piece of data that gets posted to the server (related to the click) - the _eventTarget - you will find a string something like the following "uxRepeaterItems$ctrl2$Delete"

As long as you use a naming convention for the command button IDs, this string contains everything you need to process an event:

-you can tell that the command originated in a given databound control (in this case uxRepeaterItems), you can tell that the button that was clicked was in row2 (from the ctrl2), and you can tell that the button that was clicked was the delete button. If the IDs of the items are put in the DataKey collection of the control (which used ControlState not viewState), then the specific item to which the click is related, can be identified (and subsequently retrieved from the database)

We have successfully used this technique to create our own custom versions of the Repeater and the ListView controls, that will fire command events without the need for viewstate or an initial re-databind.

It sometimes seems that there are intrinsic inefficiencies with theASP.Net framework that have to be battled in order to produce well optimized pages.  I would venture a guess that this is one of the reasons why you rarely see the really large web applications written in ASP.Net.  It is just too hard (and requires so much very specific knowledge) to get the performance required. This is a shame, as it seems it really does not need to be like this.

I would be interested to hear any thoughts on the above.

# re: TRULY Understanding ViewState

Monday, December 29, 2008 6:27 PM by InfinitiesLoop

jshallard --

If you look at what the default delete/select/etc buttons do, they post a command that is like Delete$5. That means delete what was in row 5. The ListView/GridView/etc uses that to issue the command for the appropriate row. The problem you describe arises when you use command bubbling, rather than this direct-to-the-control post command. Your solution with command bubbling is fine, but it can't be a general solution baked into the control. A command can bubble for any reason what-so-ever, it's not always the result of a post, or from a post of a particular type. Anyone can call RaiseBubbleEvent for any reason, so its not a feasible general solution.

As for the seemingly wasteful double databinding -- it does seem wasteful, but maybe not as bad as you think. First of all, the fact you databind twice doesnt mean you have to retrieve the data twice. And its quite likely that the 2nd databind is necessary to ensure the control is reflecting the data instead of user-entered values or things that have been dynamically changed across posts. The 1st binding consumes viewstate and postdata, 'completing' the life cycle of the controls from the previous request. The 2nd binding starts a whole new sequence. This happens even when viewstate is on, by the way, just that the first binding is utilizing viewstate and the second is utilizing the data.

# re: TRULY Understanding ViewState

Tuesday, December 30, 2008 6:40 PM by jshallard

Hi Dave

Thanks for your response, the input is much appreciated.  I can not reproduce one part of a solution you mentioned, and I would like to question the soundness of some assumptions you make. I hope you don't mind me challenging you on these things on your own website! I am only doing so, as you seem to have the knowledge to help move this debate forward a little.  This is something I have been bumping in to for some time now, and don't have any solutions I am really happy with.

QUESTION:

(from your previous post) "the default delete/select/etc buttons ... post a command that is like Delete$5 ... The ListView/GridView/etc uses that to issue the command for the appropriate row"

I can see this behavior in my GridView tests by using the following "<asp:ButtonField CommandName="Delete" Text="Delete" runat="server" />".  However, I cannot seem to see this behavior in the ListView (or repeater for that matter). I have been using "<asp:LinkButton CommandName="Delete" Text="Delete" runat="server" />". Could I trouble you to let me know what I am doing wrong here, as I would much prefer to do a "direct-to-the-control post command" using out of the box functionality than my custom implementation.

ASSUMPTIONS:

(from your previous post) "Anyone can call RaiseBubbleEvent for any reason, so its not a feasible general solution"

Not sure why this would be a problem.  The detailed solution can be implemented to fire the specific command event in the circumstance that the relevant post data is available.  The in built event bubbling behavior can still be left intact, to fire in the circumstances where an event has bubbled all the way to the actual event target

(from your previous post) "maybe not as bad as you think. First of all, the fact you databind twice doesn't mean you have to retrieve the data twice."

I would image that for most edit and delete actions the data would need to be refetched.  I hear your point (in the article) about database fetchs being "cheap data", but in a Service Oriented Architecture, as in our case, it is often not a direct hit to the database but a webservice call instead - and then the fetch starts to get more expensive.

(from your previous post) "The 1st binding consumes viewstate and postdata, 'completing' the life cycle of the controls from the previous request."

It is exactly the need for this 'completing' of the lifecycle that I have the hardest time with.  What does it really benefit you in the case of a databound control? It seems to be an often expensive operation that usually give you very little. And here is why I think this:

- Keeping viewstate on for large databound controls results in very large viewstate. In your article you pointed out that this was expensive, especially when taking in to account that this could be posted over a dial up modem

- Two data fetches instead of one can make a noticeable difference, especially in a SOA web application

- Often the whole process of 'completing' the lifecycle is simply to get two small pieces of data - the commandName and the commandArgument. As this data is already available, it would often be entirely unnecessary to have this completion process at all.

(from your previous post) "This happens even when viewstate is on, by the way, just that the first binding is utilizing viewstate and the second is utilizing the data."

One of the biggest concerns with operating with the viewstate off is that you have not protection against 'dirty data'.  Upon hitting delete, the first bind may be to data which has changed since the page first loaded, resulting in the wrong item being operated on (as the item in row X may no longer be the same).

THE CRUNCH

Would it be fair to say that that the options available to a developer using a listview/repeater control in ASP.Net are as follows:

1 - Keep viewstate on for the the listview/repeater, and deal with the inefficiences that come with this (i.e. very large viewstate)

2 - Turn viewstate off and risk performing operations on the wrong item when dirty reads come in to play

3 - Use a "direct-to-the-control post command".  (I have not ever seen this working with ListView so could use some guidance on this)

4 - Develop a custom list view to parse the data, as described in previous post

Options 1 & 2 seem very bad. 3 I have never seen work. 4 works, but requires using some 'hacky' string parsing, which has some problems, as you indicated.

OK, so if I can get option 3 to work we are in good shape (help please!) otherwise, we are still hurting a little.

# re: TRULY Understanding ViewState

Tuesday, January 20, 2009 3:01 PM by Ken Lange

This was an extremely useful article. Thank you for putting it together.  I've been trying to get a handle on the ins and outs of ViewState for quite some time.  I had read dozens of articles on the subject but as you say, none of them give a complete picture.

And for the record, I enjoyed the humor as well.

Ken

# ViewState: Handle with care

Wednesday, January 21, 2009 3:33 AM by Alessandro Gallo

I’m refactoring an ASP.NET application and I’ve already found several times – too many – code similar

# another problem with viewstate | keyongtech

Thursday, January 22, 2009 12:25 AM by another problem with viewstate | keyongtech

Pingback from  another problem with viewstate | keyongtech

# ASP.NET 4.0: ViewStateMode

Wednesday, January 28, 2009 10:55 AM by mostlylucid

ASP.NET 4.0: ViewStateMode

# re: TRULY Understanding ViewState

Saturday, January 31, 2009 5:44 AM by Nij

A very helpful article, thank you!

Just one point to add / note: I prefer Label and Literals to the <%= %> approach because you get to see in the designer something that is far more helpful:

"You've told us you get paid [uiSalary], and get paid [uiPayFrequency]."

...which is far more useful than...

"You've told us you get paid , and get paid.

Of course, if the designer could show the <%= %> tags then that would alleviate the issue... However, I disagree that this is better code separation: as you have just embedded knowledge of your .aspx.cs code into your ASP markup; rather than provided an 'interface' with a control.

Anyway, once again; very interesting, and I am pretty sure that you have covered some topics here that I will be revisiting in the near future!

Nij

# View State in Asp.net 4.0 | Dev Techie

Sunday, February 01, 2009 10:51 PM by View State in Asp.net 4.0 | Dev Techie

Pingback from  View State in Asp.net 4.0 | Dev Techie

# re: TRULY Understanding ViewState

Wednesday, February 04, 2009 11:34 AM by Stu Robinson

Excellent article.  I'm a fairly experienced developer but just beginning with ASP.NET.  Not onlt did this help me understand ViewState, but also ASP.NET issues in General.

Also, I LOVE the style of the article with the humor, etc.  It kept me captivated much more than if it was absent.  Thanks for taking the time to write it.

Stu

# good articles about ASP.NET ViewState

Friday, February 06, 2009 9:17 AM by Easoney

UnderstandingASP.NETViewState:

msdn.microsoft.com/.../ms972976.aspx

TRULYUnde...

# Are my assumptions about OnInit() correct? | keyongtech

Friday, February 13, 2009 12:09 PM by Are my assumptions about OnInit() correct? | keyongtech

Pingback from  Are my assumptions about OnInit() correct? | keyongtech

# re: TRULY Understanding ViewState

Tuesday, February 17, 2009 11:23 AM by JaneWilliams

Thank you! I really wish I'd read this article before developing my first ASP.Net app rather than afterwards. Sadly, the sample code I got from the initial course and on-line tutorials and examples mostly resembled Joe's :(

# FYI Good article on VIEWSTATE - Visual Basic .NET Forums

Wednesday, March 11, 2009 11:46 AM by FYI Good article on VIEWSTATE - Visual Basic .NET Forums

Pingback from  FYI Good article on VIEWSTATE - Visual Basic .NET Forums

# Yet another Death by the ViewState – Part II

Wednesday, March 18, 2009 1:28 PM by Deviations

It´s been a while since my post on ViewState. This is just a update about the article i mention that

# Click &amp; Solve &raquo; Yet another Death by the ViewState ??? Part II

Pingback from  Click &amp; Solve &raquo;  Yet another Death by the ViewState ??? Part II

# infoblog &raquo; Yet another Death by the ViewState ??? Part II

Wednesday, March 18, 2009 4:31 PM by infoblog » Yet another Death by the ViewState ??? Part II

Pingback from  infoblog &raquo; Yet another Death by the ViewState ??? Part II

# re: TRULY Understanding ViewState

Thursday, April 16, 2009 3:02 PM by Daneel

And I was thinking I was the problem...

I can't believe such important stuff is ignored in so many otherwise good books.

Let me know when you publish a book, it's a must-have.

10x !

# re: TRULY Understanding ViewState

Tuesday, April 21, 2009 11:03 AM by David

This was a very helpful article and this might be a noob question. Since .net uses viewstate to store the values of control properties that have changed, can you access viewstate on postback to determine if one of those properties (say the text property of a textbox) has changed? Not on a custom control though, just the regular TextBox control.

# Aprender ASP.NET MVC &laquo; Gerardo Contijoch

Saturday, April 25, 2009 3:07 PM by Aprender ASP.NET MVC « Gerardo Contijoch

Pingback from  Aprender ASP.NET MVC &laquo; Gerardo Contijoch

# ASP.NET 4.0 : ViewStateMode (New Property) &laquo; &lt;Blog ID=&#8221;Virendra&#8221; Text=&#8221;Virendra&#8217;s Blogs&#8221;/&gt;

Pingback from  ASP.NET 4.0 : ViewStateMode (New Property) &laquo; &lt;Blog ID=&#8221;Virendra&#8221; Text=&#8221;Virendra&#8217;s Blogs&#8221;/&gt;

# re: TRULY Understanding ViewState

Friday, May 22, 2009 2:12 PM by Arno

Excellent article, thank you!

# Disminuyendo el tama&#241;o del ViewState (parte 2)

Thursday, June 25, 2009 12:02 AM by Disminuyendo el tamaño del ViewState (parte 2)

Pingback from  Disminuyendo el tama&#241;o del ViewState (parte 2)

# re: TRULY Understanding ViewState

Sunday, July 05, 2009 4:40 AM by rohani

your article is fantastic .I've got a problem that drive me mad!!!

I have to create some controls in PreRender() event .the controls events don't fire at all.

Please guide me.

# re: TRULY Understanding ViewState

Friday, July 17, 2009 3:54 AM by Rompom

Best article ever.

# re: TRULY Understanding ViewState

Monday, July 20, 2009 9:09 AM by Martin

Keep it up doing these great kontent correct articles!... imagine all out there to be like this one...

# re: TRULY Understanding ViewState

Monday, July 20, 2009 3:15 PM by Adil

One of the best article I have ever come across over the net. I have shared this with as many web developer as I can.

Great and Simple explanation with humor to make things go easily in mind.

Thanks a lot...

# re: TRULY Understanding ViewState

Tuesday, August 04, 2009 6:26 AM by brianstewey

Nice article. I am still confused though. You say that form items intrinsically keep their values.

eg. User enters "blah" in text box which has been persisted in ViewState. This form is now posted back. Now when LoadViewState() is called wouldnt that mean that the value entered by the user will be overwritten by the ViewState?

Cheers

# re: TRULY Understanding ViewState

Tuesday, August 04, 2009 1:36 PM by InfinitiesLoop

brianstewey -- No, because postback data is loaded into controls after they've already loaded their viewstate. This is how, by the way, the textbox knows whether to raise its 'TextChanged' event.

# re: TRULY Understanding ViewState

Thursday, August 13, 2009 12:39 PM by NoHumor

Th guy ranting about too much humor is an Ass

# re: TRULY Understanding ViewState

Monday, August 24, 2009 3:54 PM by Neil Timmerman

This is the best article on viewstate...ever. Thanks for taking the time to write it. I just emailed it on to my team.

# Twitter Trackbacks for TRULY Understanding ViewState - Infinities Loop [asp.net] on Topsy.com

Pingback from  Twitter Trackbacks for                 TRULY Understanding ViewState - Infinities Loop         [asp.net]        on Topsy.com

# re: TRULY Understanding ViewState

Tuesday, September 08, 2009 7:43 AM by Bibin Babu

Great material.. made my day..

Thanks a lot

# re: TRULY Understanding ViewState

Friday, September 11, 2009 6:11 AM by geetha

is view state is expired?

# re: TRULY Understanding ViewState

Monday, September 14, 2009 10:21 AM by Robert Brower

This article kicks ass. Good job.

# ViewState Compression in ASP.NET 2.0 &laquo; Me Myself &amp; C#

Wednesday, September 16, 2009 11:26 AM by ViewState Compression in ASP.NET 2.0 « Me Myself & C#

Pingback from  ViewState Compression in ASP.NET 2.0 &laquo; Me Myself &amp; C#

# links for 2009-09-22 - sashidhar.com

Tuesday, September 22, 2009 5:07 AM by links for 2009-09-22 - sashidhar.com

Pingback from  links for 2009-09-22 - sashidhar.com

# &nbsp; &nbsp; &nbsp; |>>ASP.NET

Thursday, September 24, 2009 9:49 PM by       |>>ASP.NET

Pingback from  &nbsp; &nbsp; &nbsp; |>>ASP.NET

# re: TRULY Understanding ViewState

Monday, September 28, 2009 12:22 PM by Andrew Knox

Very useful, have been tasked recently with developing a suite of controls tailored for specific needs within our company and this article has really helped stitch together a lot of important concepts.

Great work!

# re: TRULY Understanding ViewState

Monday, September 28, 2009 2:28 PM by chamak

I Have a custom control where I create Controls dynamically based on XML. I use CreateChildControls().

Here is the code how I create Controls..

protected override void CreateChildControls()

       {

           CreateParameterControls();

           base.CreateChildControls();

       }

private void CreateParameterControls()

       {

           this.Controls.Add(new LiteralControl("<table cellpadding=0 cellspacing=0>"));

           foreach (XElement xe in this.Parms)

           {

               this.Controls.Add(new LiteralControl("<tr><td>"));

               bool required = xe.Element("REQUIRED").Value.Equals("true");

               string type = xe.Element("CONTROL").Element("TYPE").Value.ToUpper();

               string id = xe.Element("NAME").Value.ToString();

               Control control = null;

               Label label = new Label();

               label.Text = xe.Element("CONTROL").Element("LABEL").Value.ToString();

               label.ShowRequired = required;

               this.Controls.Add(label);

               System.Web.UI.WebControls.RequiredFieldValidator validator = new System.Web.UI.WebControls.RequiredFieldValidator();

               validator.Text = "";

               validator.Display = ValidatorDisplay.None;

               validator.SetFocusOnError = true;

               validator.Enabled = required;

               validator.ErrorMessage = xe.Element("CONTROL").Element("LABEL").Value.ToString() + " is required";

               validator.ControlToValidate = id;

               this.Controls.Add(validator);

               this.Controls.Add(new LiteralControl("</td><td>"));

               if (type.Equals("TEXTBOX"))

               {

                   control = CreateTextBox(id);

               }

               else if (type.Equals("DROPDOWN"))

               {

                   control = CreateDropDown(id, xe.Element("CONTROL"));

               }

               else if (type.Equals("DATE"))

               {

                   control = CreateDate(id);

               }

               else if (type.Equals("CHECKBOX"))

               {

                   control = CreateCheckBox(id);

               }

               if (control != null)

               {

                   this.Controls.Add(control);

               }

               this.Controls.Add(new LiteralControl("</td></tr>"));

           }

           this.Controls.Add(new LiteralControl("</table>"));

}

However after the post back none of my childcontrols displays the data posted.

What could be the reason its not loading the previous state?

thanks in advance

# re: TRULY Understanding ViewState

Thursday, October 01, 2009 12:30 PM by Jothi

That was a great article:):) i was struggling to understand the nuances of ViewState and now u've made the concvept crystal clear :):) Thanks a lot for such an excellent article :)!!

# re: TRULY Understanding ViewState

Friday, October 09, 2009 10:02 AM by mcutter

I have several formView pages that seem to be getting some kind of viewstate time out.  If I let the page sit for 20 min or so and then hit a control that causes a postback, ViewState.Count==0 on the next PageLoad.  This happens on a number of different pages and can be reliably reproduced.  It causes problems in various parts of the codebehind that are relying on ViewState data.  It is not a session timeout issue as session timeout is set to 240 min and the session is still intact.  Yet I don't find many internet posts on ViewState timing out.  Do you have any ideas about what might be going on here?

# re: TRULY Understanding ViewState

Friday, October 16, 2009 10:04 PM by A.Ragab

I have spent my whole day reading this but I gotta say it's outstanding and I did LOVE your style of writing :)

# re: TRULY Understanding ViewState

Thursday, October 22, 2009 5:04 PM by mcutter

Our solution to the 20 minute timeout problem was to change sessionState from inproc to sqlserver.

# re: TRULY Understanding ViewState

Friday, October 30, 2009 3:01 PM by Charger

Amazing article... For more than 3 years looks like it's been very helpful.

Congratz ;)

# re: TRULY Understanding ViewState

Tuesday, November 10, 2009 6:36 PM by Shinya

I should have read this article a year ago.. Simply, great.. Thanks!

# TRULY Understanding ViewState

Wednesday, November 11, 2009 10:32 PM by 语虫

# 理解ASP.NET中的ViewState

Tuesday, November 17, 2009 8:23 PM by Kein

以前做EasyFramework的时候,对ViewState的控制一直是个问题。后来看了一篇强文,才有点搞清楚了。由于原文很长,下面照本宣科,把要点讲一下。

在Google中搜索ASP.NETVi...

# re: TRULY Understanding ViewState

Thursday, November 19, 2009 2:42 PM by mishra.p

Excellant Article....Thanks for sharing...

# Storing ViewState into Session &laquo; TechCode

Tuesday, November 24, 2009 7:27 AM by Storing ViewState into Session « TechCode

Pingback from  Storing ViewState into Session &laquo; TechCode

Leave a Comment

(required) 
(required) 
(optional)
(required)