Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with a manually instantiated SessionState provider

I'm working on a prototype program, which should test different (SessionState, Profile, etc) providers for ASP.NET, i.e. MySQL, Oracle, etc. At the moment I'm using the MySQL provider. I've just managed to instantiate the provider, a SessionStateContainer and the SessionState itself.

Type mySqlType = Type.GetType("MySql.Web.SessionState.MySqlSessionStateStore, MySql.Web, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", true, true);

SessionStateStoreProviderBase provider = (SessionStateStoreProviderBase)Activator.CreateInstance(mySqlType);
System.Collections.Specialized.NameValueCollection providerConfig = new System.Collections.Specialized.NameValueCollection();
providerConfig.Add("connectionStringName", "LocalMySqlServer");
providerConfig.Add("applicationName", "/");
providerConfig.Add("autogenerateschema", "True");
providerConfig.Add("enableExpireCallback", "False");

provider.Initialize("MySqlSessionStateProvider", providerConfig);

HttpContext context = new HttpContext(
                          new HttpRequest("fake", "http://localhost:14359", ""),
                          new HttpResponse(new StringWriter()));

SessionStateStoreData storeData = provider.CreateNewStoreData(context, 100);
System.Web.SessionState.HttpSessionStateContainer sessionStateContainer =
    new System.Web.SessionState.HttpSessionStateContainer(
            "mySession",
            storeData.Items,
            storeData.StaticObjects,
            100,
            true,
            System.Web.HttpCookieMode.UseDeviceProfile,
            SessionStateMode.Custom,
            false
    );

Type sessionStateType = Type.GetType("System.Web.SessionState.HttpSessionState, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
HttpSessionState sessionState =
    (HttpSessionState)sessionStateType
        .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(IHttpSessionState) }, null)
        .Invoke(new object[] { ssessionStateContainer });

provider.InitializeRequest(context);

Everything seems to be working fine, as I'm able to write some values, in the session I created, and I'm able to read them from there:

sessionStateContainer.Add("SomeKey", "SomeValue");
var test = sessionStateContainer["SomeKey"];
Console.WriteLine("var test: " + test.ToString()); // outputs "var test: SomeValue"

sessionState.Add("AnotherKey", "SomeOtherValue");
var test2 = sessionState["AnotherKey"];
Console.WriteLine("var test2: " + test2.ToString()); // outputs "var test2: SomeOtherValue"

// End the request
provider.EndRequest(context);

Here comes the interesting part - when I inspect the my_aspnet_sessions table in the DB, there is nothing in there.

So I'm wondering where has the data been written or am I doing something wrong?

Update:
Even though this issue is no longer a blocker, I'm still curious to know and if anyone is up for giving it a try, here's the connectionString I've used:

<connectionStrings>
  <remove name="LocalMySqlServer" />
  <add name="LocalMySqlServer" connectionString="server=localhost;database=session_test;User Id=user;password=pass" providerName="MySql.Data.MySqlClient" />
</connectionStrings>

You'd also need the MySQL Connector NET.

like image 704
Havelock Avatar asked Apr 04 '13 20:04

Havelock


1 Answers

You see no data in the database because the SessionStateModule waits for the request end to invoke the command SetAndReleaseItemExclusive. The data are kept in memory until such command has been called. Indeed the documentation states:

The SessionStateModule object calls the SetAndReleaseItemExclusive method at the end of a request, during the ReleaseRequestState event, to insert current session-item information into the data store or update existing session-item information in the data store with current values, to update the expiration time on the item, and to release the lock on the data. Only session data for the current application that matches the supplied session id and lockId values is updated. For more information about locking, see "Locking Session Store Data" in the SessionStateStoreProviderBase class overview.

To dive further into details, you can take a look at the relevant files from the mono codebase.

Given this, to see your session data in the database you should execute something like:

object storeLockId = new object();
sessionStateContainer.Add("SomeKey", "SomeValue");
var test = sessionStateContainer["SomeKey"];
Console.WriteLine("var test: " + test.ToString());

sessionState.Add("AnotherKey", "SomeOtherValue");
var test2 = sessionState["AnotherKey"];
Console.WriteLine("var test2: " + test2.ToString()); 

// End the request
provider.SetAndReleaseItemExclusive (context, sessionStateContainer.SessionID, 
                                     storeData, storeLockId, true);
provider.EndRequest(context);
like image 157
Giacomo Tesio Avatar answered Oct 18 '22 21:10

Giacomo Tesio