56

I am trying to share sessions between two web applications, both hosted on the same server. One is a .net 2.0 web forms application the other is as .net 3.5 MVC2 application.

Both apps have their session set up like this:

<sessionState
      mode="StateServer"
      stateConnectionString="tcpip=127.0.0.1:42424"
      />

In the webform application I am posting the the session key to the MVC app:

protected void LinkButton1_Click(object sender, EventArgs e)
{
    Session["myvariable"] = "dan"; 
    string sessionKey = HttpContext.Current.Session.SessionID;

    //Followed by some code that posts sessionKey to the other application    
}

I then recieve it in the MVC application and try use the same session like this:

[HttpPost]
public  void Recieve(string sessionKey )
{
    var manager = new SessionIDManager();

    bool redirected;
    bool IsAdded;

     manager.SaveSessionID(HttpContext.ApplicationInstance.Context, Id, out redirected, out IsAdded);
     var myVar = Session["myvariable"];

}

The key is being posted but the session does not seem to get loaded in the MVC app, i.e. sessionKey is null. Can what I am trying to do be done?

Dan
  • 29,100
  • 43
  • 148
  • 207
  • Can you post the code for posting Session id to other application – kk1076 Jan 10 '13 at 06:49
  • https://blogs.msdn.microsoft.com/toddca/2007/01/25/sharing-asp-net-session-state-across-applications/ – yakya May 27 '16 at 15:17
  • The link in @sotn comment (https://blogs.msdn.microsoft.com/toddca/2007/01/25/sharing-asp-net-session-state-across-applications/) shows how to cause the SQL session provider to return the same application id for all applications, so that they effectively share the same session –  Mar 27 '17 at 21:10

3 Answers3

79

I did it this way:

Basically the idea is both apps use native .net sessionState stored in sqlserver. By using the same machine key and making a small tweak to a stored procedure – both apps can share any session keys and/or forms authenication.

Both apps would do something like this in their web.config:

<sessionState mode="SQLServer" sqlConnectionString="Data Source=.\SQLEXPRESS;User Id=test;Password=test;Application Name=AppName"  />
    <machineKey
validationKey="SOMEKEY"
validation="SHA1" decryption="AES"
/>

Session state db would need to be set up on a database server, that both apps can see.

Docs for doing this: http://msdn.microsoft.com/en-us/library/ms229862(VS.80).aspx

Command that would need to be run: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>aspnet_regsql.exe -E -ssadd --sstype p -S .\SQLEXPRESS

Stored procedure (TempGetAppID) tweak to:

 @appId int OUTPUT
AS

    -- start change

    -- Use the application name specified in the connection for the appname if specified
    -- This allows us to share session between sites just by making sure they have the
    -- the same application name in the connection string.
    DECLARE @connStrAppName nvarchar(50)
    SET @connStrAppName = APP_NAME()

    -- .NET SQLClient Data Provider is the default application name for .NET apps
    IF (@connStrAppName <> '.NET SQLClient Data Provider')
        SET @appName = @connStrAppName

    -- end change

SET @appName = LOWER(@appName)
Knelis
  • 6,782
  • 2
  • 34
  • 54
Dan
  • 29,100
  • 43
  • 148
  • 207
  • 1
    For the stored procedure (assuming your not gonna need a more scalable solution) you might just hardcode the appname: `SET @appName = LOWER("MyAppNameHere")` – Colin Pear Oct 03 '12 at 17:43
  • 2
    Life isn't so perfect. This solution has some mistake. I've been starting to use it and noticed that outdated session rows aren't removed from db. So it extremely grows and I get exception "The transaction log for database 'ASPState' is full." after some time. How can I fix it? – RredCat Nov 06 '12 at 09:13
  • Moreover ASPState_log.LDF takes ~50GB 8| – RredCat Nov 06 '12 at 09:30
  • 1
    Select Tasks -> Shrink -> Database and ALTER DATABASE [ASPState] SET RECOVERY SIMPLE GO helped me. – RredCat Nov 06 '12 at 11:53
  • 2
    @RredCat: By using aspnet_regsql.exe with the -sstype p parameter when setting up the database he is selecting a persisted datastore. Leave this parameter off and it will default to using the "tempdb" database. – Aidan Black Dec 04 '13 at 01:13
  • @Dan Can you post the code for posting Session id to other application? The `@appId int OUTPUT` value in C# code ? – Kiquenet Oct 14 '16 at 16:35
10

The problem is that session keys are scoped to the applications, so two applications having the same session key in fact have separate sessions.

You can do one of two things:

  1. Put both applications as a virtual directory under a common IIS Application. I don't think this is a good idea, but it will work.

  2. Roll your own session data solution for the data you want to share. Possibly using the backend database as the common storage, if you have one that is.

Based on Justin's comment, just to clarify option 2 is not refering to the SQL state managemet for out of process sessions. I mean for you to actually manually manage the shared data for the two sessions, possibly using a database.

Kenny Evitt
  • 9,291
  • 5
  • 65
  • 93
Chris Taylor
  • 52,623
  • 10
  • 78
  • 89
  • I was going to suggest using the database for session management solution as well. It's very easy to setup but you might run into the same problem different apps will have different keys and can't share data. – Justin May 19 '10 at 19:03
  • @Justin, I am not suggesting that the OP use the ASP.NET session in SQL Server. This will definately have the same issue, session keys in ASP.NET are scoped to the Application, regardless of the persistence. I mean the OP should entirely manage the storage of the shared data "manually" and only use the ASP.NET session mechanism for the application specific session data if required. – Chris Taylor May 19 '10 at 19:08
  • @Dan, the thing is that you are mixing two applications into one scope. You now not only share session data, but but have both application loaded into the same appdomain, where static data, application variables, cache variable all potentially impact each other, just because you wanted to share session data. – Chris Taylor May 20 '10 at 17:37
  • @Chris Taylor - if I am reading this (https://blogs.msdn.microsoft.com/toddca/2007/01/25/sharing-asp-net-session-state-across-applications/) right, you can, with a trivial change, modify the sql session provider to use the same applicaiton id for all applications, so that the session information is no longer scoped per application. –  Mar 27 '17 at 21:15
0

You can use a common Machine key to generate same Session ID inside both applications for a given user. Additionally, you should also plan on storing sessions of both applications in a common store such as ASP.NET State Service or a distributed cache.

You can use NCache distributed cache which takes provides session sharing feature between different applications. You specify same Application ID tag for both apps inside session state settings which allows you to share session object provided you have same Session ID generated for both applications.