Wednesday, April 16, 2008 2:16 PM
ViewState is used inside your controls mostly for keeping track of variables on PostBacks. So basically if you have a variable or a property inside your WebUserControl and you want it to persist values, this is when you use the ViewState. However it is important to understand that the ViewState data is put in the page response itself as a Hidden field, what does this mean?
This means that first, you can not trust the input from your ViewState, as it comes back with the page post so it can be changed. By default the ViewState is not encrypted, however you can instruct IIS to encrypt it but it will affect performance. For example if you put in your ViewState an ID of a record to update, do not update it without asserting that it actually belongs to the logged in user, a full security discussion is beyond this post.
Second this means that your page's response size will grow as the data you save in your ViewState grows; this affects performance as it will take more time for your end user's browser to load the page and it will take more time when he wants to post back to your server. If you want to check this, when you get your page from your server, save it as an html file from your browser and check its size. There is also some extra processing in Serializing/Deserializing the ViewState. So in short, the more you save data in your ViewState, the more your suffer from performance.
So what happens when you have some large data that you have to save in your ViewState and there isn't a better solution for it. You can use a combination of your ViewState and Session to give you the same results, but with much lesser performance degradation. The trick is to save your large data inside your session with a certain generated key and just save that key inside your ViewState. For an example, suppose you have a DataSet that you want to keep track on post backs, you write some code like this.
public DataSet SavedDataSource
{
get
{
if (ViewState["SavedDataSourceKey"] == null)
return null;
return (DataSet)Session[(string)ViewState["SavedDataSourceKey"]];
}
set
{
if (ViewState["SavedDataSourceKey"] == null && value == null)
return;
if (ViewState["SavedDataSourceKey"] == null)
ViewState["SavedDataSourceKey"] = System.Guid.NewGuid().ToString();
if (value == null)
{
Session.Remove((string)ViewState["SavedDataSourceKey"]);
ViewState.Remove("SavedDataSourceKey");
}
else
Session[(string)ViewState["SavedDataSourceKey"]] = value;
}
}
By using your Session to save your large data, you are saving on the response size and also on the PostBack size, and your data is kept on your server.
A word of caution:
Please note that you are now saving your data in your Session, this means you have to be careful not to overuse this method excessively as your Session will grow on the server per user, so do not use this method frequently unless you need to use this trick when you have large data. Moreover if you know when you can dispose of your variable, do it as soon as you can by setting your property to null, this will release the session data. For example if you know you are navigating to another page and you will no longer get PostBacks on your page, then set the SavedDataSource to null to release the Session data.