using System.Web.UI.Adapters;
namespace Adapter
{
public class Adapter: System.Web.UI.Adapters.PageAdapter
{
public override PageStatePersister GetStatePersister()
{
return new SessionPageStatePersister(this.Page);
}
}
<browser refID="default">
<controladapters>
<adapter controltype="System.Web.UI.Page">
adapterType="Adapter.Adapter" />
</controladapters>
</browser>
SessionPageStatePersister is built into the .NET Framework, so our adapter can just new it up and return it in the GetStatePersister function. If we want to build a PageStatePersister with AppFabric, however, we've got a bit more work to do. We need a class that inherits from PageStatePersister so we can implement the Save and Load methods.
using System.Web.UI;
using System.Web.UI.WebControls;
namespace AppFabricPageStatePersister
{
public class Persister : System.Web.UI.PageStatePersister
{
public Persister(Page page) : base(page)
{
}
private const string HiddenFieldId = "StateIdHiddenField";
public override void Load()
{
// Read page's incoming state Id from hidden field
string stateIdString = Page.Request.Form[HiddenFieldId];
Pair cachedState = (Pair) CacheHelper.Get(stateIdString);
ViewState = cachedState.First;
ControlState = cachedState.Second;
}
public override void Save()
{
Pair statePair;
// Build a Pair from the Page's View- and ControlState
statePair = new Pair(ViewState, ControlState);
// Generate a new ID to use as the key for storing in the cache
Guid stateId = Guid.NewGuid();
// Put the Pair in the cache
CacheHelper.Put(stateId.ToString(), statePair);
// Write the key out into the page in a hidden field so we can get it back later
Page.ClientScript.RegisterHiddenField(HiddenFieldId, stateId.ToString());
}
}
}
CacheHelper is an abstraction over AppFabric so my Persister class isn't cluttered with calls to the AppFabric objects:
using Microsoft.ApplicationServer.Caching;
namespace AppFabricPageStatePersister
{
class CacheHelper
{
public static object Get(string Key)
{
DataCacheFactory factory;
DataCache cache;
string cacheName;
factory = new DataCacheFactory();
cacheName = WebConfigurationManager.AppSettings["StatePersistenceCacheName"].ToString();
cache = factory.GetCache(cacheName);
return cache.Get(Key);
}
public static void Put(string Key, object Value)
{
DataCacheFactory factory;
DataCache cache;
string cacheName;
factory = new DataCacheFactory();
cacheName = WebConfigurationManager.AppSettings["StatePersistenceCacheName"].ToString();
cache = factory.GetCache(cacheName);
cache.Put(Key, Value);
}
}
}
The adapter is straightforward - like the SessionPageStatePersister adapter, all it needs to do is return a new instance of AppFabricPageStatePersister, and the .browser file just needs to point at AppFabricPageStatePersister.Adapter.
namespace AppFabricPageStatePersister
{
public class Adapter : System.Web.UI.Adapters.PageAdapter
{
public override System.Web.UI.PageStatePersister GetStatePersister()
{
return new Persister(this.Page);
}
}
}
<browser refID="default">
<controlAdapters>
<adapter controlType="System.Web.UI.Page"
adapterType="AppFabricPageStatePersister.Adapter" />
</controlAdapters>
</browser>
Simples.
Download this demo code: C# VB
* Yes, I know you could put your Session state in AppFabric and continue to use the SessionPageStatePersister but I'm assuming you can't/don't want to use Session state.













