Last week I wrote an article suggesting cleaner ways of using ViewState to store local page variable state. I got some great feedback on that post and this blog is an extension on the topic that I came up with while experimenting with the various techniques brought up.
One of the things I look for in page level coding techniques is simplicity. "Write less, do more", but keep it simple. By simple, I mean easy to write and easy for someone else to read and maintain.
One of the challenges of using ViewState in a simple and efficient way is that it can get wordy. What I mean is with most approaches you end up typing in the variable name three or four times to set up a local variable and an associated property or you set up a local variable and then save and load it during SaveViewState and LoadViewState. All in all, for every variable you end up with multiple lines of declarative code.
After poking it over and over I came up with the idea to use a struct to remove the need for multiple lines of code per variable. Here's the result:
[Serializable()]
protected struct ViewStateStruct
{
public int EmployeeID;
public byte[] Version;
}
protected ViewStateStruct _vs = new ViewStateStruct();
protected override object SaveViewState()
{ this.ViewState.Add("_vs", _vs); return base.SaveViewState(); }
protected override void LoadViewState(object savedState)
{ base.LoadViewState(savedState); _vs = (ViewStateStruct)ViewState["_vs"]; }
As you can see, if you want to add a variable, you only have to declare it in one place inside the struct. Throughout your code all your ViewState variables are simply referenced by _vs.EmployeeID. If you don't like _vs, then it's easy to change it. Either way, be sure to set a standard name for the struct throughout your project.
In my previous blog on the topic, Tony pointed out an article on CodeProject called Using Attributes for encapsulating ASP.Net Session and ViewState variables. Combining this with the struct idea yields you with the following code in your page.
[Serializable()]
protected struct ViewStateStruct
{
public int EmployeeID;
public byte[] Version;
}
[PersistField(Location = PersistLocation.ViewState)]
protected ViewStateStruct _vs = new ViewStateStruct();
On the general topic of "write less, do more", there's one other thing I remembered while playing with this and Linq to SQL in the same page. I found when I went to load data from my Linq object to my form fields, I also needed to store the same value in my ViewState variable so that when the page came back, I'd have access to the original value. In C# you can do this:
tbName.Text = _vs.Name = employee.Name;
I seldom remember that but it's pretty useful.