Recently I was asked how one could share session state between two ASP.NET 2.0 applications. Well I had to be totally honest; I had never even looked into this and really did not know why one would want to do this. Well when I was queried about a solution for this problem a couple times by different folks within a week I decided to take a look at the problem and not worry about why anyone would want to share state cross application. Besides who am I to say what people will use or not use, I thought EBAY was a horrible idea when I first heard about it years ago, I though damn everyone will just take your money and not send you the products….
My first thought was that we should write a custom SQL provider that addresses the problem however writing a custom session state provider is not trivial and I like trivial solutions. Out of the box SQL session state can handle storing session from multiple web applications and it prevents session from being shared. The various session state items are stored in a single table ‘ASPStateTempSessions’ using a SessionId as a primary key. The SessionId is actually the string representation of the SessionId used to identify the user’s session plus the ApplicationId. The ApplicationId is created when the session state provider calls the ‘TempGetAppID’ stored procedure. This proc either creates the id by hashing the application name or returns the id stored for the name in the ASPStateTempApplications table. For each web application that is using a database for session state you will have a row in ASPStateTempApplications that represents that application.
So to work around this segmentation I modified the TempGetAppID stored procedure to always return the same Application ID (in my case ‘1’) and I use a new application name of ‘Global Session State Application’. Now any ASP.NET 2.0 web application that you point to this state database will be able to share session.
After the modification to the stored proc I verified the changes have taken effect by looking at the SessionID column in the ASPStateTempSessions table. I now see values like: ’13clw2vlrjio0d45opi0qg4500000001‘ and ‘gz3wc5nqeq2es2ezzxfzpbyb00000001‘, note the last 8 characters of these strings that is my new global application ID.
Here are the changes that I made to the stored procedure. Note that before you run this on your SQL box you may want to empty your ASPStateTempApplications and ASPStateTempSessions tables for general housecleaning. Also you will want to bounce your ASPNet Applications since they only call TempGetAppId stored procedure when the session state module is loaded.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER OFF
ALTER PROCEDURE [dbo].[TempGetAppID]
@appId int OUTPUT
SET @appName = LOWER(‘Global Session State Application’)
SET @appId = 1
SELECT @appId = AppId
FROM [ASPNET Session State].dbo.ASPStateTempApplications
WHERE AppId = 1
IF @appId IS NULL BEGIN
INSERT [ASPNET Session State].dbo.ASPStateTempApplications
Note about testing —I have done minimal testing with this solution so please do you own testing and let me know your results. I look forward to your feedback.