[Download Source Code]
Scott hinted in his article of what I proposed to him - to use global unique identifiers (commonly known as GUID) to differentiate between multiple instances of the page. For those who do not know of what a GUID is, it is a randomly drawn number that is 128 bits in length. It is almost guaranteed that any GUID that is computed by the computer will be not only unique to that machine but also guaranteed that it would be unique throughout the world.
Essentially, my solution follows the simple logic of:
- On every page request, a GUID will automatically generate.
- That GUID will then be used to name the view state file.
- For keeping records for the next post back, the GUID is saved to a hidden field because we want to keep reference to the view state (file) which was used for that request.
- When post back occurs, the GUID is read from the hidden field that was assigned in step three.
- From there on, a new GUID is then created and the cycle repeats itself from step one until the user does not post back by moving onto another page or closing the browser window.
With the logic explained in point form above; here is my version of my view state persister. The file name is called "PersistViewStateToFileSystem2.cs" in the downloadable source. Here is the code of my version of the PersistViewStateToFileSystem class with self-explanatory comments:
public class PersistViewStateToFileSystem : Page {
// the extension is to protect users from sniffing in on view state via a simple
// HTTP request
private const string FilePathFormat = "~/PersistedViewState/{0}.vs.resource";
private const string ViewStateHiddenFieldName = "__ViewStateGuid";</font>
<font face="Verdana" size="2"> // creates a new instance of a GUID for the current request
private Guid pViewStateFilePath = Guid.NewGuid();</font>
<font face="Verdana" size="2"> /// <summary>
/// The path for this page's view state information (GUID based).
/// </summary>
public string ViewStateFilePath {
get {
return MapPath(String.Format(FilePathFormat, pViewStateFilePath.ToString()));
}
}</font>
<font face="Verdana" size="2"> /// <summary>
/// Saves the view state to the Web server file system.
/// </summary>
protected override void SavePageStateToPersistenceMedium(object viewState) {
// serialize the view state into a base-64 encoded string
LosFormatter los = new LosFormatter();
StringWriter writer = new StringWriter();</font>
<font face="Verdana" size="2"> // save the view state to disk
los.Serialize(writer, viewState);
StreamWriter sw = File.CreateText(ViewStateFilePath);
sw.Write(writer.ToString());
sw.Close();</font>
<font face="Verdana" size="2"> // saves the view state GUID to a hidden field
Page.RegisterHiddenField(ViewStateHiddenFieldName, ViewStateFilePath);
}</font>
<font face="Verdana" size="2"> /// <summary>
/// Loads the page's view state from the Web server's file system.
/// </summary>
protected override object LoadPageStateFromPersistenceMedium() {
string vsString = Request.Form[ViewStateHiddenFieldName];</font>
<font face="Verdana" size="2"> if (!File.Exists(vsString))
throw new Exception("The Viewstate file " + vsString + " is missing!!!");
else {
// instantiates the formatter and opens the file
LosFormatter los = new LosFormatter();
StreamReader sr = File.OpenText(vsString);
string viewStateString = sr.ReadToEnd();</font>
<font face="Verdana" size="2"> // close file and deserialize the view state
sr.Close();
return los.Deserialize(viewStateString);
}
}
}