HowTo: Persist viewstate on the server-side

In our last web project we had some performance issues, mainly caused by the extremely big page viewstate of our asp.net pages. If you then add Ajax capabilities to your site, using UpdatePanels, you really get in trouble. Why that? Well that's because of the fact that on each asynchronous postback caused by an UpdatePanel, the whole viewstate is transferred back and forth to the server. So for instance to fetch a list of 10 items from the server which may make up about 6 KB of text, you will instead transfer an amount of ~800 KB (more or less in our case, I don't remember exactly) because the viewstate (of the whole page) that has to be transferred to the server back and forth.
So an immediate solution which we've implemented is to not transfer the viewstate to the client, but to directly persist it down on the hard disk of the server. It maybe is not the best solution but it gave us a quick performance boost since we were approaching the deadline. This persisting of the viewstate can be done by overriding the SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium as shown in the code sample below:

// the extension is to protect users from sniffing in on view state via a simple
// HTTP request
private const string FilePathFormat = "~/sys/temp/{0}.vs.resource";
private const string ViewStateHiddenFieldName = "__ViewStateGuid";

// creates a new instance of a GUID for the current request
private Guid pViewStateFilePath = Guid.NewGuid();

/// <summary>
/// The path for this page's view state information (GUID based).
/// </summary>
public string ViewStateFilePath
{
get
{
return MapPath(String.Format(FilePathFormat, pViewStateFilePath.ToString()));
}
}


protected override void SavePageStateToPersistenceMedium(object viewState)
{
// serialize the view state into a base-64 encoded string
LosFormatter los = new LosFormatter();
StringWriter writer = new StringWriter();

// save the view state to disk
los.Serialize(writer, viewState);
using (StreamWriter sw = File.CreateText(ViewStateFilePath))
{
sw.Write(writer.ToString());
sw.Close();
}
// saves the view state GUID to a hidden field
base.SavePageStateToPersistenceMedium(new Pair(null, ViewStateFilePath));

}

protected override object LoadPageStateFromPersistenceMedium()
{
Pair vs = base.LoadPageStateFromPersistenceMedium() as Pair;
if (vs != null)
{
if (!File.Exists(vs.Second.ToString()))
throw new Exception("The Viewstate file " + vs.Second.ToString() + " is missing!!!");
else
{
// instantiates the formatter and opens the file
LosFormatter los = new LosFormatter();
string viewStateString = String.Empty;
using (
StreamReader sr = File.OpenText(vs.Second.ToString()))
{
viewStateString = sr.ReadToEnd();

// close file and deserialize the view state
sr.Close();
}
return los.Deserialize(viewStateString);
}
}
else
return null;

}

But pay attention, if you're using a load balancing router, your load balancing strategy has to be configured properly because otherwise you may have trouble in loading the correct viewstate.
Kindle

Comments

0

Your ad here?