7

我正在开发一个原型程序,它应该为 ASP.NET 测试不同的(SessionState、Profile 等)提供程序,即 MySQL、Oracle 等。目前我正在使用 MySQL 提供程序。我刚刚成功地实例化了提供者、SessionStateContainer 和 SessionState 本身。

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);

一切似乎都运行良好,因为我可以在我创建的会话中写入一些值,并且我可以从那里读取它们:

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);

有趣的部分来了——当我检查my_aspnet_sessions数据库中的表时,里面什么都没有。

所以我想知道数据写在哪里或者我做错了什么?

更新:
即使这个问题不再是一个障碍,我仍然很想知道,如果有人愿意尝试一下,这是connectionString我用过的:

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

您还需要MySQL Connector NET

4

2 回答 2

3

您在数据库中看不到任何数据,因为SessionStateModule等待请求结束以调用命令SetAndReleaseItemExclusive。数据一直保存在内存中,直到调用了这样的命令。确实,文档指出:

SessionStateModule 对象在请求结束时调用 SetAndReleaseItemExclusive 方法,在 ReleaseRequestState 事件期间,将当前会话项信息插入数据存储或使用当前值更新数据存储中现有的会话项信息,以更新到期时间在项目上,并释放对数据的锁定。仅更新与提供的会话 id 和 lockId 值匹配的当前应用程序的会话数据。有关锁定的更多信息,请参阅 SessionStateStoreProviderBase 类概述中的“锁定会话存储数据”。

要进一步了解细节,您可以查看mono 代码库中的相关文件

鉴于此,要在数据库中查看会话数据,您应该执行以下操作:

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);
于 2013-04-14T14:58:07.130 回答
0

在您的 web.config 中,您需要设置 mode="custom"

 <sessionState mode="Custom" customProvider="YourProvider">

否则,无论提供者如何,会话数据都将存储在内存中。

于 2013-04-13T07:37:53.990 回答