sharing session state classic asp asp.net

Sharing Session State between Classic ASP and .NET

Posted on Updated on

At work, we are starting to upgrade/migrate a Classic ASP application to multiple ASP.NET MVC Web and WebApi 2.x applications. One of the requirements is the need to share session state between old and new web applications.

  1. Required to access the Classic ASP session state variable.
  2. Required to share session state between multiple web applications.

Step #1:
The following code is in a page called AspSession.asp in the classic asp application.

<% 
'------------------------------------------------------------------------------
if Session.Contents.Count = 0 then
    response.Write "Session.Contents.Count = 0"
    response.End
end if

'------------------------------------------------------------------------------
Dim values,remoteAddr,localAddr

remoteAddr = Request.ServerVariables("REMOTE_ADDR")
localAddr = Request.ServerVariables("LOCAL_ADDR")

'------------------------------------------------------------------------------
if remoteAddr = localAddr then
    strMode = Request.QueryString( "mode" )
    strName = Request.QueryString( "name" )

    if strMode = "get" then
        response.Write GetSessionVar( strName )
    elseif strMode = "getall" then
        response.Write GetAllSessionVars()
    elseif strMode = "set" then
        strValue = Request.QueryString( "value" )
        Session( strName ) = strValue
    end if
end if

'------------------------------------------------------------------------------
function GetAllSessionVars()
    dim sessionVars

    sessionVars = ""
    for each key in Session.Contents
        sessionVars = sessionVars & "{" & GetSessionVar( key ) & "}"
    next

    GetAllSessionVars = sessionVars
end function

'------------------------------------------------------------------------------
' returns a single session variable
function GetSessionVar( byval name )

    If IsArray(Session.Contents(name)) Then
        GetSessionVar = GetArrayVar
    ElseIf IsObject( Session.Contents(name) ) Then
        GetSessionVar = GetObjectDictionaryVar( name )
    Else
        GetSessionVar = name & "|" & Session.Contents(name)
    End If

end function

'------------------------------------------------------------------------------
' assumes this is an object/dictionary session variable.
function GetObjectDictionaryVar( byval name )
    dim values

    values = name & "[Object/Dictionary]"
    for each key in Session.Contents(name)
        values = values & key & ":" & Session.Contents(name)(key) & "|"
    next

    GetObjectDictionaryVar = values
end function

'------------------------------------------------------------------------------
' assumes this is an array session variable.
function GetArrayVar( byval name )
    dim values

    values = name & "[Array]"
    for each key in Session.Contents(name)
        values = values & key & ":" & Session.Contents(name)(key) & "|"
    next

    GetArrayVar = values
end function
%>

Step #2:
In the ASP.NET MVC web application, create a class SessionStateManager.cs. This is a generic class using .NET Session State Management. We are developing a system that uses multiple ASP.NET MVC web applications and this class is used by all of the applications and placed into a separate class library.

The appName in the URL is the path where the AspSession.asp file is located.

// Contains properties, etc for session state management. This class needs to be
// serializable so it can be saved in session state.
[Serializable]
public class SessionStateManager
{
    //-------------------------------------------------------------------------
    // This calls a web page in the classic asp application to get it's 
    // current session variables.
    public static object Get( string name )
    {
        HttpContext context = HttpContext.Current;
        if ( context == null )
            return string.Empty;

        string value = null;
        foreach ( string key in context.Request.Cookies.AllKeys )
        {
            HttpCookie cookie = context.Request.Cookies[key];
            if ( cookie != null )
            {
                if ( cookie.Name.StartsWith( "ASPSESSION" ) )
                {
                    System.Uri uri = context.Request.Url;
                    string url = string.Format( "{0}://{1}/appName/aspSession.asp?mode=get&name={2}",
                                                 uri.Scheme, uri.Host, name );
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
                    request.Headers.Add( "Cookie: " + cookie.Name + "=" + cookie.Value );
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream responseStream = response.GetResponseStream();
                    if ( responseStream != null )
                    {
                        System.Text.Encoding encode = System.Text.Encoding.GetEncoding( "utf-8" );
                        StreamReader readStream = new StreamReader( responseStream, encode );
                        value = readStream.ReadToEnd();
                        response.Close();
                        readStream.Close();

                        // if true then it is either the wrong cookie or an expired cookie
                        // and will eventually be removed by the system.
                        if ( value.Equals( "Session.Contents.Count = 0" ) )
                        {
                            value = null;
                            continue;
                        }

                        string[] item;
                        if ( value.StartsWith( name + "[Object/Dictionary]" ) )
                        {
                            value = value.Replace( name + "[Object/Dictionary]", "" );
                            Dictionary<string,string> dictionary = new Dictionary<string, string>();
                            string[] dictionaryItems = value.Split( '|' );
                            foreach ( string s in dictionaryItems )
                            {
                                item = s.Split( ':' );
                                if ( item.Length == 2 )
                                    dictionary.Add( item[0], item[1] );
                            }
                            return dictionary;
                        }

                        item = value.Split( '|' );
                        if ( item.Length == 2)
                            value = (item.Length == 2) ? item[1] : string.Empty;
                    }
                }
            }
        }
        return value;
    }

    //-------------------------------------------------------------------------
    //  Disclaimer: This method hasn't been tested.
    //  Use this to set a session variable in the classic asp application. 
    public static void Set( string name, object value )
    {
        HttpContext context = HttpContext.Current;
        String[] cookies = context.Request.Cookies.AllKeys;

        foreach ( string key in context.Request.Cookies.AllKeys )
        {
            HttpCookie cookie = context.Request.Cookies[key];
            if ( cookie != null && cookie.Name.StartsWith( "ASPSESSION" ) )
            {
                System.Uri uri = context.Request.Url;
                string url = string.Format( "{0}://{1}/appName/aspSession.asp?mode=set&name={2}&value={3}",
                                            uri.Scheme, uri.Host,
                                            context.Server.UrlEncode( name ),
                                            context.Server.UrlEncode( value.ToString() ) );
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
                request.Headers.Add( "Cookie: " + cookie.Name + "=" + cookie.Value );
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                break;
            }
        }
    }
}