Been trying to find the original article...but I can't so I'll hunt it down later...this code is basically just a rehashed version of that other guy's original with a few of my own enhancements...so, first thisn to get the ViewState to live on your server:
Use a BasePage class which all your ASP.NET pages inherit from, note I use a Config class referenced from Global to hold stuff like filenames, directories etc...you can just substiute the appropriate values (I'll cover this in more detail in a later post):
So past this code into your BasePage:
private static string FilePathFormat = Global.Config.ViewStateServerPath + "{0}" + Global.Config.ViewStateFileExtension;
private const string ViewStateHiddenFieldName = "__ViewStateGuid";
// creates a new instance of a GUID for the current request
private string pViewStateFilePath = Guid.NewGuid().ToString();
/// <summary>
/// The path for this page's view state information (GUID based).
/// </summary>
public string ViewStateFilePath
{
get
{
return MapPath(String.Format(FilePathFormat, pViewStateFilePath));
}
}
/// <summary>
/// Saves the view state to the Web server file system.
/// </summary>
protected override void SavePageStateToPersistenceMedium(object viewState)
{
if(Global.Config.ServerBasedViewState)
{
// serialize the view state into a base-64 encoded string
LosFormatter los = new LosFormatter();
// save the view state to disk
StreamWriter sw = File.CreateText(ViewStateFilePath);
los.Serialize(sw, viewState);
sw.Close();
// saves the view state GUID to a hidden field
Page.RegisterHiddenField(ViewStateHiddenFieldName, pViewStateFilePath);
}
else
{
base.SavePageStateToPersistenceMedium(viewState);
}
}
/// <summary>
/// Loads the page's view state from the Web server's file system.
/// </summary>
protected override object LoadPageStateFromPersistenceMedium()
{
if(Global.Config.ServerBasedViewState)
{
string vsGuid = Request.Form[ViewStateHiddenFieldName];
string vsString = MapPath(String.Format(FilePathFormat, vsGuid));
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();
// close file and deserialize the view state
sr.Close();
return los.Deserialize(viewStateString);
}
}
else
{
return base.LoadPageStateFromPersistenceMedium();
}
}
This just overrides the default ViewState behaviour, saving the ViewState instead to a file on your server...all that's inserted in the page is a simple GUID (the original used a filename with path - which isn't really a secure thing to do).
Next, you want to clean up these files occasionally. Original used an HttpModule with a Thread.Sleep() to control the cleanup cycle...I just used a Timer like so:
using System;
using System.IO;
using System.Timers;
using System.Web;
using Microsoft.ApplicationBlocks.ExceptionManagement;
namespace Utility
{
/// <summary>
/// Summary description for ViewStateCleaner.
/// </summary>
public class ViewStateCleaner
{
public bool TimerStarted = false;
private static Timer _cleanupTimer;
private static int _expiryMinutes = Global.Config.ViewStateTimeout;
public void startTimer()
{
if(_cleanupTimer == null)
{
_cleanupTimer = new Timer();
}
_cleanupTimer.Interval =TimeSpan.FromMinutes(_expiryMinutes).TotalMilliseconds;
if(!TimerStarted)
{
_cleanupTimer.Elapsed+=new ElapsedEventHandler(_cleanupTimer_Elapsed);
_cleanupTimer.Start();
}
}
public void CleanupFiles()
{
string viewStatePath = HttpContext.Current.Server.MapPath(Global.Config.ViewStateServerPath);
long nowTicks = DateTime.Now.Ticks;
long expTicks = TimeSpan.FromMinutes(_expiryMinutes).Ticks;
foreach(string fileName in Directory.GetFiles(viewStatePath))
{
long diffTicks = nowTicks - File.GetCreationTime(fileName).Ticks;
if(diffTicks >expTicks )
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: no