The Windows Azure Platform Training Kit http://go.microsoft.com/fwlink/?LinkID=130354 includes a great Hands-On Lab for Session State support in Windows Azure. In case you haven’t seen it yet – it’s in the Lab “Building ASP.NET Applications with Windows Azure”, Exercise 3, Task 4.
After looking at this, I wondered how to best implement this, from scratch, in an existing application using out-of-the-box ASP.NET session state support.
So first, I set myself up a bare metal Azure Cloud project in Visual Studio, just adding a simple Web Role (in principle following Task 1 in the first exercise of the Hands-On Lab “Introduction to Windows Azure”).
Then, in the Default.aspx of that application, I added a bit of text, a text box (“SessStateValue”), a label (“ProcessId”) and a button (“SessStateUpdate”):
This got a bit of code-behind in the Default.aspx.cs file:
public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ProcessId.Text = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); if (this.IsPostBack) return; if (Session["Variable"] == null) SessStateValue.Text = "(not set)"; else SessStateValue.Text = Session["Variable"].ToString( ); } protected void SessStateUpdate_Click(object sender, EventArgs e) { if ((SessStateValue.Text == "") || (SessStateValue.Text == "(not set)")) Session["Variable"] = null; else Session["Variable"] = SessStateValue.Text; } }
public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ProcessId.Text = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); if (this.IsPostBack) return; if (Session["Variable"] == null) SessStateValue.Text = "(not set)"; else SessStateValue.Text = Session["Variable"].ToString( ); }
protected void SessStateUpdate_Click(object sender, EventArgs e) { if ((SessStateValue.Text == "") || (SessStateValue.Text == "(not set)")) Session["Variable"] = null; else Session["Variable"] = SessStateValue.Text; } }
Now, I configured the Web Role to run in 3 instances and got myself the perfect example of how it should NOT be – 3 independently running Role Instances, all maintaining their own session state in-memory. Easy to verify, as well:
Now I Right-Mouse-Clicked the Solution in Visual Studio and selected “Add… Existing Project”, navigated to the “Labs\BuildAspNetAppsWithWindowsAzure\Source\Assets\AspProviders” subfolder of the Training kit and added the “AspProviders” project.
First, I added a reference to the provider project in my Web Role project so that the compiler will pick up the code from the provider project to make it available in my Azure Solution.
Second, I included the following fragment into the web.config of my Web Role project:
<!-- SessionState Provider Configuration --> <sessionState mode="Custom" customProvider="TableStorageSessionStateProvider"> <providers> <clear/> <add name="TableStorageSessionStateProvider" type ="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"/> </providers> </sessionState>
Third, I double-clicked my Role configuration:
and added a configuration String called “DataConnectionString”, pointing it at my favourite storage location (for now, Development Storage):
Now I ran up the solution again and ran the same test as above. All problems solved – regardless of which process picked up the request, the state remained the same.
Even though the Table Storage provider isn’t perfect (e.g. it doesn’t do any regular clean-up of old session state entries), it can help work as a stop-gap session state solution until the Windows Azure AppFabric Session State provider http://www.microsoft.com/windowsazure/appfabric/overview/default.aspx becomes available.