There comes a time in every ASP.NET developer’s life when the need arises for information to be persisted into ViewState. For the sake of this post I’m not really interested in the reasons why. What I am interested in is how.
How do you interact with your ViewState?
I’ve seen two methods in use in the various codebases that I’ve worked on. The first that I’ll demonstrate is the most common form I’ve seen.
Let’s pretend we have a web form which has a property called MyMagicValue which needs to be stored across postbacks.
Most developers would do something like this:
protected int MyMagicValue { get { return (int)ViewState["MyMagicValue"]; } set { ViewState["MyMagicValue"] = value; } }
Information is stored directly in the ViewState hash/dictionary by accessing the ViewState property that exists on every web form/control. In this case there’s a danger of things going horribly wrong “get” is invoked before “set”!
The second isn’t so common. In fact, the only times I’ve seen it in a codebase is when I’ve implemented it myself. This leads me to believe that most of the time developers don’t even know that this method exists. Here’s the code:
private int _myMagicValue; protected int MyMagicValue { get { return _myMagicValue; } set { _myMagicValue = value; } } protected override object SaveViewState() { object[] state = new object[2]; state[0] = _myMagicValue; state[1] = base.SaveViewState(); return state; } protected override void LoadViewState(object savedState) { if (savedState != null) { object[] state = (object[])savedState; if (state.Length > 0) { _myMagicValue = (int)state[0]; base.LoadViewState(state[1]); } } }
Quite a bit different from the first version. But which one is better? Which is considered best practice? Which has the better performance?
I haven’t done any extensive research into this topic other than chatting to a workmate or two. So I wouldn’t say that I have hard data to back up what I’m about to say.
It seems to me that the latter implementation is preferrable for the following reasons:
- Your page/control contains the usual definitions for container variables, just like most other classes without references to ViewState in every property definition.
- You’re not spreading references to ViewState all through your code.
- You’re not indexing into the ViewState hash for every since get/set for a given property.
- If you want to add something else to the ViewState you can easily add it in the two overridden functions without affecting other areas of the code.
- You don’t have to worry about checking for null in the getters.
- You could easily rip out the implementation and store in another class without a great deal of refactoring or code modification.
The former is preferrable to many coders because:
- It’s less code to write.
- They don’t know that the latter method exists.
So what’s the verdict? Which of these is better, or considered “best practice”?
Edit: As per my comment below about using System.Web.UI.Pair, I thought I would add an example of how this should be used. It’s not overly pretty when you get more and more values to store, but I still prefer it to directly manipulating the ViewState object.
protected override object SaveViewState() { return new Pair(base.SaveViewState(), _myMagicValue); } protected override void LoadViewState(object savedState) { if (savedState != null) { Pair state = object as Pair; if(state != null) { base.LoadViewState(state.First); _myMagicValue = (int)state.Second; } } }
This doesn’t look so bad with just a single value, but for each value you add to the ViewState you need another Pair instance.











May 22, 2008
I like to use the following pattern:
public string Name
{
get { return (string)ViewState["name"] ?? “Default Name”; }
set { ViewState["name"] = value; }
}
Note: this does not work for value types.
Your method is the most correct. I believe it is underused because people do not like getting too deep into the leaky abstraction which is the ASP.NET page life-cycle.
May 22, 2008
this is a sweet improvement.
May 22, 2008
I’d agree with you, most people don’t want to do more work, even if it’s considered better practice.
A few people via IM have suggested that the first method is “best practice” but I can’t see any evidence anywhere. In general, people just like to take the lazy route, despite the fact that it doesn’t work for value types (as you stated).
If the former is considered best practice, then why do the function overrides exist?
May 22, 2008
Another person just mentioned that the idea of using object arrays is unsafe.
Surely then the ViewState as whole is unsafe, since it’s just a hash of objects?
As far as using an array of objects is concerned it’s not the only way to do it. Arguable you should use the System.Web.UI.Pair to chain your viewstate bits together — it looks like that class was designed just for that purpose. The resulting code is a little more tedious, but just as effective.
May 22, 2008
@LB: I think so too mate. I’ll continue to use the function overrides I think. I just feel that direct access to the ViewState is a bit of a code smell.