2013-04-04 5 views
7

Ich arbeite an einem Prototyp-Programm, das verschiedene (SessionState, Profile, etc) -Provider für ASP.NET, dh MySQL, Oracle usw. testen soll. Im Moment verwende ich der MySQL-Anbieter. Ich habe gerade den Provider, einen SessionStateContainer und den SessionState selbst instanziiert.Problem mit einem manuell instanziierten SessionState-Provider

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

Alles scheint gut zu funktionieren, wie ich bin in der Lage, einige Werte in der Sitzung, die ich erstellt, und ich bin in der Lage zu schreiben, sie von dort zu lesen:

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

komme der interessante Teil - wenn ich die my_aspnet_sessions Tabelle in der DB inspiziere, dort ist nichts darin.

Ich frage mich also, wo die Daten geschrieben wurden oder mache ich etwas falsch?

Update:
Auch wenn dieses Problem nicht mehr ist ein Blocker, ich bin immer noch neugierig zu wissen, und wenn jemand es versuchen für die Aufgabe ist, hier ist die connectionString ich verwendet habe:

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

Sie benötigen auch die MySQL Connector NET.

+0

können Sie die Daten in dieser Zeile werden Clearing durch die Schaffung neuer '.Invoke (neues Objekt [] {} ssessionStateContainer) "Was passiert, wenn du durch den Code gehst, siehst du irgendwelche Daten?" – MethodMan

+0

Die zwei Schnipsel sind in der gleichen Reihenfolge in meinem Code. Das Schreiben der Daten erfolgt nach der Instantiierung von 'sessionState', so dass ich nicht sehe, wie es gelöscht werden könnte? Wenn ich durch den Code gehe, sehe ich die Schlüssel "SomeKey" und "AnotherKey" in den entsprechenden Eigenschaften, aber mehr als das - nicht. – Havelock

Antwort

3

Sie sehen keine Daten in der Datenbank, da SessionStateModule auf das Ende der Anforderung wartet, um den Befehl SetAndReleaseItemExclusive aufzurufen. Die Daten werden solange im Speicher gehalten, bis ein solcher Befehl aufgerufen wird. Tatsächlich ist die Dokumentation heißt es:

Die Session Objekt am Ende einer Anfrage die SetAndReleaseItemExclusive Methode aufruft, während des Release Ereignis, aktuelle Session-Elementinformationen in den Datenspeicher oder aktualisieren bestehende Session-Elementinformationen in den einfügen Datenspeicher mit aktuellen Werten, um die Ablaufzeit für das Element zu aktualisieren und die Sperre für die Daten aufzuheben. Nur Sitzungsdaten für die aktuelle Anwendung, die mit den angegebenen Sitzungs-IDs und LockId-Werten übereinstimmen, werden aktualisiert. Weitere Informationen zum Sperren finden Sie unter "Sperren von Sitzungsspeicherdaten" in der SessionStateStoreProviderBase-Klassenübersicht.

Um tiefer ins Detail zu tauchen, können Sie sich die relevant files from the mono codebase ansehen.

dies gegeben, um Ihre Sitzungsdaten in der Datenbank sehen Sie so etwas wie ausführen soll:

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

Ich habe einen Anruf der 'EndRequest()' Methode des Providers. Habe gerade den Codeausschnitt in meiner Frage aktualisiert. – Havelock

+0

@Havelock wie Sie [hier] (https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.SessionState_2.0/SessionSQLServerHandler.cs#l529) sehen können endRequest von stateprovider ist oft leer. Das ** SessionStateModule ** ruft ** SetAndReleaseItemExclusive ** im ** [OnRequestEnd] (https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.SessionState_2) auf. 0/SessionStateModule.cs # L325) Handler ** (über [OnReleaseRequestState] (https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.SessionState_2.0/SessionStateModule) .cs # L278)). –

+0

Beachten Sie, dass die MS.NET-Implementierung natürlich anders sein kann, aber das Verhalten des Monos ist konform mit der Dokumentation (um Portierungsprobleme zu minimieren). –

0

In Ihrem web.config, müssen Sie den Modus = "custom"

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

Andernfalls Sitzungsdaten im Speicher des Anbieters, unabhängig gespeichert werden einzustellen.

+0

Der Modus 'Custom' wird angegeben, wenn der 'HttpSessionStateContainer sessionStateContainer' instanziiert wird (siehe obigen Code).Die Überprüfung der Felder beim Debugging hat ergeben, dass der Modus tatsächlich "Benutzerdefiniert" ist. Das ist also nicht das Problem. – Havelock

+0

@Havelock - versuchen Sie, mysql Protokollierung einzuschalten. Sehen Sie, ob überhaupt etwas an mysql gesendet wird. Vielleicht wird es an die DB geschickt, aber nicht begangen. –

+0

Gute Idee, aber es hat leider nicht geholfen. – Havelock