2013-04-04 6 views
7

Pracuję nad programem prototypowym, który powinien przetestować różnych dostawców (SessionState, Profile, itp.) Dla ASP.NET, tj. MySQL, Oracle itp. W tej chwili używam dostawca MySQL. Właśnie udało mi się utworzyć instancję dostawcy, SessionStateContainer i samego SessionState.Problem z ręcznie utworzonym dostawcą 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); 

Wszystko wydaje się działać dobrze, jak jestem w stanie napisać niektóre wartości, w sesji I stworzył, a ja jestem w stanie odczytać je stamtąd:

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

Nadchodzi interesująca część - kiedy sprawdzam tabelę my_aspnet_sessions w DB, nic tam nie ma.

Zastanawiam się, gdzie zostały zapisane dane lub czy robię coś nie tak?

Aktualizacja:
Choć ta kwestia nie jest już bloker, wciąż jestem ciekaw, a jeśli ktoś jest gotowy do nadając jej spróbować, oto connectionString Użyłem:

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

Będziesz także potrzebować MySQL Connector NET.

+0

można być wyczyszczenie danych w tej linii, tworząc nowy '.Invoke (nowy obiekt [] {} ssessionStateContainer); "co się stanie, gdy przejdziesz przez kod, czy w ogóle widzisz jakieś dane? – MethodMan

+0

Dwa fragmenty są w tej samej kolejności w moim kodzie. Zapis danych kończy się po utworzeniu 'sessionState', więc nie widzę, jak można to wyczyścić? Podczas przechodzenia przez kod widzę klucze 'SomeKey' i' AnotherKey' w odpowiednich właściwościach, ale więcej - nie. – Havelock

Odpowiedz

3

Nie widzisz żadnych danych w bazie danych, ponieważ SessionStateModule czeka na zakończenie żądania, aby wywołać polecenie SetAndReleaseItemExclusive. Dane są przechowywane w pamięci do momentu wywołania tego polecenia. Rzeczywiście dokumentacja stwierdza:

Przedmiotem SessionStateModule wywołuje SetAndReleaseItemExclusive metodę na końcu wniosku, podczas imprezy ReleaseRequestState, aby wstawić aktualne informacje sesji artykuł do magazynu danych lub zaktualizować istniejące informacje sesji pozycja w magazyn danych z bieżącymi wartościami, aby zaktualizować czas wygaśnięcia elementu i zwolnić blokadę danych. Aktualizowane są tylko dane sesji dla bieżącej aplikacji, które pasują do dostarczonego identyfikatora sesji i wartości lockId. Aby uzyskać więcej informacji o blokowaniu, zobacz "Blokowanie danych sesji sesji" w opisie klasy SessionStateStoreProviderBase.

Aby zanurkować bardziej szczegółowo, można spojrzeć na relevant files from the mono codebase.

Biorąc pod uwagę to, aby zobaczyć swoich danych sesji w bazie danych należy wykonać coś takiego:

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

Mam wywołanie metody "EndRequest()" dostawcy. Właśnie zaktualizowałem fragment kodu w moim pytaniu. – Havelock

+0

@Havelock jak widać [tutaj] (https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.SessionState_2.0/SessionSQLServerHandler.cs#l529) EndRequest stateprovider jest często pusty. ** ** SessionStateModule ** wywołuje ** SetAndReleaseItemExclusive ** w ** [OnRequestEnd] (https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.SessionState_2. 0/SessionStateModule.cs # L325) handler ** (przez [OnReleaseRequestState] (https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.SessionState_2.0/SessionStateModule .cs # L278)). –

+0

Należy zauważyć, że oczywiście implementacja MS.NET może być inna, ale zachowanie Mono jest zgodne z dokumentacją (w celu zminimalizowania problemów z portowaniem). –

0

W Twojej web.config trzeba ustawić tryb = „zwyczaj”

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

przeciwnym razie dane sesji będą zapisywane w pamięci niezależnie od operatora.

+0

Tryb 'Niestandardowy' jest określony podczas tworzenia instancji' HttpSessionStateContainer sessionStateContainer' (patrz powyższy kod).Sprawdzanie pól podczas debugowania pokazało, że tryb rzeczywiście jest "niestandardowy", więc to nie problem. – Havelock

+0

@Havelock - spróbuj włączyć rejestrowanie mysql. Sprawdź, czy coś jest wysyłane do MySQL w ogóle. Może jest wysyłany do DB, ale nie jest zatwierdzony. –

+0

Dobry pomysł, ale niestety nie pomógł. – Havelock

Powiązane problemy