Implementieren eines Sitzungszustandsspeicher-Anbieters
Aktualisiert: November 2007
Beschreibt eine benutzerdefinierte Implementierung des Sitzungszustandsspeicher-Anbieters und stellt das Implementieren eines Beispielanbieters dar.
Der ASP.NET-Sitzungszustand ermöglicht es Ihnen, Benutzersitzungsdaten in anderen Quellen zu speichern. Standardmäßig werden Sitzungszustandswerte und -informationen im Arbeitsspeicher innerhalb des ASP.NET-Prozesses gespeichert. Alternativ können Sie die Sitzungsdaten auch auf einem Zustandsserver ablegen, wodurch die Zustandsdaten in einem unabhängigen Prozess gespeichert werden. Dadurch bleiben die Daten auch dann erhalten, wenn die ASP.NET-Anwendung heruntergefahren und neu gestartet wird. Eine weitere Alternative besteht darin, die Sitzungsdaten in einer SQL Server-Datenbank abzulegen, auf die mehrere Webserver gemeinsam zugreifen können.
Sie können die in ASP.NET enthaltenen Sitzungszustandsspeicher verwenden oder einen eigenen Sitzungszustand-Speicheranbieter implementieren. Es kann aus folgenden Gründen sinnvoll sein, einen benutzerdefinierten Sitzungszustandsspeicher-Anbieter zu erstellen:
Sie müssen die Sitzungszustandsinformationen in einer anderen Datenquelle als SQL Server ablegen, wie etwa einer FoxPro- oder einer Oracle-Datenbank.
Sie müssen Sitzungszustandsinformationen mit einem Datenbankschema verwalten, das vom Datenbankschema der Anbieter abweicht, die mit dem .NET Framework geliefert werden. Das können beispielsweise Einkaufswagendaten sein, die mit einem vordefinierten Schema in der vorhandenen SQL Server-Datenbank gespeichert werden.
Einen benutzerdefinierten Sitzungszustandsspeicher-Anbieter können Sie implementieren, indem Sie eine Klasse erstellen, die von der SessionStateStoreProviderBase-Klasse erbt. Weitere Informationen finden Sie im Abschnitt "Erforderliche Klassen" weiter unten.
Das Sitzungszustandsmodul
Der Sitzungszustand wird von der SessionStateModule-Klasse verwaltet, die den Sitzungszustandsspeicher-Anbieter aufruft, um Sitzungsdaten zu verschiedenen Zeiten während einer Anforderung aus dem Datenspeicher zu lesen und in diesen zu schreiben. Zu Beginn einer Anforderung werden von der SessionStateModule-Instanz Daten aus der Datenquelle abgerufen, indem entweder die GetItemExclusive-Methode oder die GetItem-Methode aufgerufen wird, wenn das EnableSessionState-Seitenattribut auf ReadOnly festgelegt ist. Wenn die Sitzungszustandsvariablen geändert wurden, wird von der SessionStateModule-Instanz am Ende der Anforderung die SessionStateStoreProviderBase.SetAndReleaseItemExclusive-Methode aufgerufen, um die aktualisierten Werte in den Sitzungszustandsspeicher zu schreiben. Vom SessionStateModule werden zusätzliche Member der SessionStateStoreProviderBase-Implementierung aufgerufen, um eine neue Sitzung zu initialisieren und um die Sitzungsdaten aus dem Datenspeicher zu löschen, wenn die HttpSessionState.Abandon-Methode aufgerufen wird. Die einzelnen Member der SessionStateStoreProviderBase-Klasse werden im Abschnitt "Erforderliche Klassen" weiter unten ausführlich erklärt.
Die SessionStateModule-Klasse bestimmt den SessionID-Wert direkt, nicht über den Sitzungszustandsspeicher-Anbieter. Falls erforderlich, können Sie einen benutzerdefinierten SessionIDManager implementieren, indem Sie eine Klasse erstellen, die von der ISessionIDManager-Schnittstelle erbt. Weitere Informationen finden Sie im ISessionIDManager im Abschnitt “Hinweise“.
Für den Zugriff auf geschützte Ressourcen, z. B. einen Datenbankserver, wird das SessionStateModule auf die ASP.NET-Prozessidentität zurückgesetzt. Sie können angeben, dass die SessionStateModule-Instanz die von IIS bereitgestellte Identität annimmt, indem Sie das useHostingIdentity-Attribut des <sessionState>-Konfigurationselements auf false festlegen. Wenn Sie beispielsweise Ihre IIS-Anwendung für die integrierte Sicherheitsfunktion von Windows konfiguriert haben und in ASP.NET die von IIS zur Verfügung gestellte Identität für die Sitzungsverwaltung verwenden möchten, geben Sie in der Datei Web.config der Anwendung im Konfigurationsabschnitt <system.web> den Wert <identity impersonate="true" /> an und legen das useHostingIdentity-Attribut des <sessionState>-Konfigurationselements auf false fest. Wenn das useHostingIdentity-Attribut den Wert true hat, übernimmt ASP.NET für die Verbindung mit der Datenquelle die Prozessidentität oder die Benutzerinformationen aus dem <identity>-Konfigurationselement (falls vorhanden). Weitere Informationen über die ASP.NET-Prozessidentität finden Sie unter Konfigurieren der Prozessidentität in ASP.NET und Identitätswechsel in ASP.NET
Sperren von Sitzungsspeicherdaten
ASP.NET-Anwendungen sind Multithreadanwendungen, sodass sie auf mehrere gleichzeitige Anforderungen reagieren können. Mehrere Anforderungen könnten zur gleichen Zeit versuchen, auf die gleichen Sitzungsinformationen zuzugreifen. Stellen Sie sich ein Szenario vor, in dem mehrere Frames in einem Frameset auf ASP.NET-Webseiten in derselben Anwendung zugreifen. Die einzelnen Anforderungen für jeden Frame des Framesets können auf dem Webserver in verschiedenen Threads gleichzeitig ausgeführt werden. Wenn die ASP.NET-Seiten für die einzelnen Frames auf Sitzungszustandsvariablen zugreifen, kann es vorkommen, dass mehrere Threads gleichzeitig auf den Sitzungsspeicher zugreifen. Zur Vermeidung von Datenkollisionen im Sitzungsspeicher und unerwartetem Sitzungszustandsverhalten enthalten die SessionStateModule-Klasse und die SessionStateStoreProviderBase-Klasse eine Funktion, über die das Sitzungsspeicherelement für eine bestimmte Sitzung während der Ausführung einer ASP.NET-Seite exklusiv gesperrt wird. Beachten Sie, dass ein Sitzungsspeicherelement nicht gesperrt wird, wenn es mit dem EnableSessionState-Attribut als ReadOnly gekennzeichnet ist. Trotzdem können möglicherweise andere ASP.NET-Seiten derselben Anwendung in den Sitzungsspeicher schreiben, sodass unter Umständen auch eine Anforderung schreibgeschützter Sitzungsdaten aus dem Speicher warten muss, bis die gesperrten Daten freigegeben werden.
Die Sitzungsspeicherdaten werden zu Beginn der Anforderung bei Aufruf der GetItemExclusive-Methode gesperrt. Wenn die Anforderung abgeschlossen ist, wird die Sperre während des Aufrufs der SetAndReleaseItemExclusive-Methode aufgehoben.
Wenn die SessionStateModule-Instanz beim Aufruf von GetItemExclusive oder der GetItem-Methode auf gesperrte Sitzungsdaten stößt, werden die Sitzungsdaten in Halbsekundenintervallen neu angefordert, bis entweder die Sperre aufgehoben ist oder die in der ExecutionTimeout-Eigenschaft angegebene Zeit vergangen ist. Bei einer Zeitüberschreitung der Anforderung wird die ReleaseItemExclusive-Methode vom SessionStateModule aufgerufen, um die Sitzungsspeicherdaten freizugeben und gleichzeitig die Sitzungsspeicherdaten anzufordern.
Unter Umständen wurden die Sitzungsspeicherdaten durch Aufruf der ReleaseItemExclusive-Methode von einem anderen Thread bereits vor dem Aufruf der SetAndReleaseItemExclusive-Methode für die aktuelle Antwort freigegeben. Dies könnte bewirken, dass die SessionStateModule-Instanz Sitzungszustandsspeicher-Daten festlegt und freigibt, die bereits von einer anderen Sitzung freigegeben und geändert wurden. Um dies zu vermeiden, wird jeder Anforderung zum Ändern gesperrter Sitzungsspeicherdaten vom SessionStateModule ein Sperrkennzeichner hinzugefügt. Die Sitzungsspeicherdaten werden nur geändert, wenn der Sperrkennzeichner im Datenspeicher mit dem vom SessionStateModule übergebenen Sperrkennzeichner übereinstimmt.
Löschen von Speicherdaten abgelaufener Sitzungen
Wenn die Abandon-Methode für eine Sitzung aufgerufen wird, werden die Daten dieser Sitzung mit der RemoveItem-Methode aus dem Datenspeicher gelöscht. Andernfalls verbleiben die Daten im Sitzungsdatenspeicher und stehen für zukünftige Anforderungen in der Sitzung zur Verfügung.
Der Löschmechanismus für Daten abgelaufener Sitzungen hängt von den Funktionen Ihrer Datenquelle ab. Wenn sich Ihre Datenquelle so konfigurieren lässt, dass Daten abgelaufener Sitzungen anhand der Timeout-Eigenschaft der Sitzung gelöscht werden, können Sie die SetItemExpireCallback-Methode verwenden, um auf den Delegaten für das Session_OnEnd-Ereignis zu verweisen und das Ereignis beim Löschen abgelaufener Sitzungsdaten auszulösen.
ApplicationName
Um den Gültigkeitsbereich der Sitzung zu erhalten, speichern Sitzungszustandsspeicher-Anbieter die Sitzungsinformationen für jede Anwendung eindeutig. Somit kann dieselbe Datenquelle von mehren ASP.NET-Anwendungen verwendet werden, ohne dass es zu einem Konflikt wegen doppelter Sitzungs-IDs kommt.
Da Sitzungszustandsspeicher-Anbieter Sitzungsinformationen für jede Anwendung eindeutig speichern, müssen Sie sicherstellen, dass das Datenschema, die Abfragen und die Aktualisierungen den Anwendungsnamen enthalten. Zum Abrufen von Sitzungsdaten aus einer Datenbank wird beispielsweise der folgende Befehl verwendet:
SELECT * FROM Sessions
WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication'
Alternativ können Sie eine Kombination aus der Sitzungs-ID und dem Anwendungsnamen als eindeutiger ID für ein Element im Sitzungszustands-Datenspeicher ablegen.
Erforderliche Klassen
Zum Implementieren eines Sitzungszustandsspeicher-Anbieters erstellen Sie eine Klasse, die von der abstrakten Klasse SessionStateStoreProviderBase erbt. Die SessionStateStoreProviderBase-Klasse erbt ihrerseits von der abstrakten Klasse ProviderBase. Folglich müssen Sie die erforderlichen Member der ProviderBase-Klasse ebenfalls implementieren. In den folgenden Tabellen sind die Eigenschaften und Methoden aufgeführt, die Sie aus der abstrakten Klasse ProviderBase und aus der abstrakten Klasse SessionStateStoreProviderBase implementieren müssen. Außerdem finden Sie dort eine Beschreibung der beiden abstrakten Klassen. Eine Implementierung jedes Members finden Sie unter Beispiel für einen Sitzungszustandsspeicher-Anbieter.
Erforderliche ProviderBase-Member
Member |
Beschreibung |
---|---|
Initialize-Methode |
Verwendet den Namen des Anbieters und eine NameValueCollection-Instanz der Konfigurationseinstellungen als Eingabe. Diese Methode wird dazu verwendet, Eigenschaftenwerte für die Anbieterinstanz festzulegen. Dazu gehören implementierungsspezifische Werte und Optionen, die in der Konfigurationsdatei (Machine.config oder Web.config) angegeben sind. |
Erforderliche SessionStateStoreProvider-Member
Member |
Beschreibung |
---|---|
InitializeRequest-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung als Eingabe und führt alle für Ihren Sitzungszustandsspeicher-Anbieter erforderlichen Initialisierungen durch. |
EndRequest-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung als Eingabe und führt alle für Ihren Sitzungszustandsspeicher-Anbieter erforderlichen Bereinigungen durch. |
Dispose-Methode |
Gibt vom Sitzungszustandsspeicher-Anbieter nicht mehr verwendete Ressourcen frei. |
GetItemExclusive-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung und den SessionID-Wert der aktuellen Anforderung als Eingabe. Ruft Sitzungswerte und -informationen aus dem Sitzungsdatenspeicher ab und sperrt die Sitzungselementdaten im Datenspeicher für die Dauer der Anforderung. Mithilfe der GetItemExclusive-Methode werden mehrere Ausgabeparameterwerte festgelegt, die das aufrufende SessionStateModule über den Zustand des aktuellen Sitzungszustandselement im Datenspeicher informieren. Wenn keine Sitzungselementdaten im Datenspeicher gefunden werden, wird mit der GetItemExclusive-Methode der Ausgabeparameter locked auf false festgelegt und null zurückgegeben. Dadurch wird das SessionStateModule veranlasst, die CreateNewStoreData-Methode aufzurufen, um ein neues SessionStateStoreData-Objekt für die Anforderung zu erstellen. Wenn Sitzungselementdaten im Datenspeicher gefunden werden, aber die Daten gesperrt sind, legt die GetItemExclusive-Methode den Ausgabeparameter locked auf true fest und legt den Ausgabeparameter lockAge auf das aktuelle Datum und die aktuelle Uhrzeit abzüglich des Datums und der Uhrzeit des Sperrvorgangs fest. Außerdem wird der Ausgabeparameter lockId auf den vom Datenspeicher abgerufenen Sperrkennzeichner festgelegt und der Wert null zurückgegeben. Dadurch wird das SessionStateModule veranlasst, nach Ablauf eines Intervalls von einer halben Sekunde die GetItemExclusive-Methode erneut aufzurufen, die Sitzungselementdaten abzurufen und eine Sperre auf die Daten zu legen. Wenn der Wert des lockAge-Ausgabeparameters den ExecutionTimeout-Wert übersteigt, ruft das SessionStateModule die ReleaseItemExclusive-Methode auf, um die Sperre von den Sitzungselementdaten zu entfernen, und ruft dann erneut die GetItemExclusive-Methode auf. Der actionFlags-Parameter wird für Sitzungen verwendet, deren Cookieless-Eigenschaft den Wert true hat, wenn das regenerateExpiredSessionId-Attribut auf true festgelegt ist. Ein actionFlags-Wert von InitializeItem (1) zeigt an, dass es sich bei dem Eintrag im Sitzungsdatenspeicher um eine neue Sitzung handelt, die initialisiert werden muss. Noch nicht initialisierte Sitzungsdatenspeicher werden durch Aufrufen der CreateUninitializedItem-Methode erstellt. Wenn das Element aus dem Sitzungsdatenspeicher bereits initialisiert ist, wird der actionFlags-Parameter auf Null (0) festgelegt. Wenn Ihr Anbieter Sitzungen ohne Cookies unterstützt, legen Sie den actionFlags-Ausgabeparameter auf den vom Sitzungsdatenspeicher für das aktuelle Element zurückgegebenen Wert fest. Wenn der actionFlags-Parameterwert für das angeforderte Sitzungsspeicherelement gleich dem InitializeItem-Enumerationswert (1) ist, wird mit der GetItemExclusive-Methode der Wert im Datenspeicher auf den Wert Null (0) festgelegt, nachdem der actionFlagsout-Parameter festgelegt wurde. |
GetItem-Methode |
Diese Methode erfüllt die gleichen Aufgaben wie die GetItemExclusive-Methode, legt jedoch keine Sperre auf das Sitzungselement im Datenspeicher. Die GetItem-Methode wird aufgerufen, wenn das EnableSessionState-Attribut auf ReadOnlyfestgelegt wird. |
SetAndReleaseItemExclusive-Methode |
Verwendet als Eingabe die HttpContext-Instanz der aktuellen Anforderung, den SessionID-Wert der aktuellen Anforderung, ein SessionStateStoreData-Objekt mit den zu speichernden aktuellen Sitzungsdaten, den Sperrkennzeichner für die aktuelle Anforderung und einen Wert, der angibt, ob die Daten für eine neue oder eine vorhandene Sitzung gespeichert werden sollen. Wenn der newItem-Parameter den Wert true hat, wird mit der SetAndReleaseItemExclusive-Methode ein neues Element mit den angegebenen Werten in den Datenspeicher eingefügt. Andernfalls wird das vorhandene Element im Datenspeicher mit den übergebenen Werten aktualisiert und die Sperre aufgehoben. Beachten Sie, dass nur Sitzungsdaten der aktuellen Anwendung aktualisiert werden, die mit dem angegebenen SessionID-Wert und dem übergebenen Sperrkennzeichner übereinstimmen. Nach Aufruf der SetAndReleaseItemExclusive-Methode wird die ResetItemTimeout-Methode vom SessionStateModule aufgerufen, um Ablaufdatum und -zeit der Sitzungselementdaten zu aktualisieren. |
ReleaseItemExclusive-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung, den SessionID-Wert der aktuellen Anforderung sowie den Sperrkennzeichner der aktuellen Anforderung als Eingabe und hebt die Sperre des Elements im Sitzungsdatenspeicher auf. Diese Methode wird aufgerufen, wenn die GetItem-Methode oder die GetItemExclusive-Methode aufgerufen wurde und der Datenspeicher angibt, dass das angeforderte Element gesperrt ist, das Alter der Sperre jedoch den ExecutionTimeout-Wert übersteigt. Die Sperre wird von dieser Methode gelöscht und das Element für die Verwendung durch andere Anforderungen freigegeben. |
RemoveItem-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung, den SessionID-Wert der aktuellen Anforderung und den Sperrkennzeichner der aktuellen Anforderung als Eingabe. Wenn das Datenspeicherelement mit dem angegebenen SessionID-Wert der aktuellen Anwendung und dem angegebenen Sperrenkennzeichner übereinstimmt, werden die Sitzungsinformationen aus dem Datenspeicher gelöscht. Diese Methode wird bei Aufruf der Abandon-Methode aufgerufen. |
CreateUninitializedItem-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung, den SessionID-Wert der aktuellen Anforderung sowie den Sperrkennzeichner der aktuellen Anforderung als Eingabe und fügt dem Sitzungsspeicher ein nicht initialisiertes Element mit einem actionFlags-Wert von InitializeItem hinzu. Die CreateUninitializedItem-Methode wird bei Sitzungen ohne Cookies verwendet, wenn das regenerateExpiredSessionId-Attribut den Wert true hat. In diesem Fall generiert das SessionStateModule einen neuen SessionID-Wert, wenn es auf eine abgelaufene Sitzungs-ID stößt. Das Verfahren zur Generierung eines neuen SessionID-Werts erfordert es, den Browser auf eine URL umzuleiten, die die neu generierte Sitzungs-ID enthält. Die CreateUninitializedItem-Methode wird bei der ersten Anforderung aufgerufen, die eine abgelaufene Sitzungs-ID enthält. Nachdem das SessionStateModule einen neuen SessionID-Wert zum Ersetzen der abgelaufenen Sitzungs-ID erhalten hat, wird die CreateUninitializedItem-Methode aufgerufen, um dem Sitzungsdatenspeicher einen nicht initialisierten Eintrag hinzuzufügen. Der Browser wird dann auf die URL mit dem neu generierten SessionID-Wert umgeleitet. Durch den nicht initialisierten Eintrag im Sitzungsdatenspeicher wird gewährleistet, dass die umgeleitete Anforderung mit dem neu generierten SessionID-Wert nicht mit der Anforderung einer abgelaufenen Sitzung verwechselt wird. Sie wird stattdessen wie eine neue Sitzung behandelt. Der nicht initialisierte Eintrag im Sitzungsdatenspeicher wird dem neu generierten SessionID-Wert zugeordnet. Er enthält nur Standardwerte wie Ablaufdatum und -zeit sowie einen Wert, der dem actionFlags-Parameter der GetItem-Methode und der GetItemExclusive-Methode entspricht. Der nicht initialisierte Eintrag im Sitzungszustandsspeicher sollte einen actionFlags-Wert enthalten, der mit dem InitializeItem-Enumerationswert (1) übereinstimmt. Dieser Wert wird von den Methoden GetItem und GetItemExclusive an das SessionStateModule übergeben. Er gibt für das SessionStateModule an, dass die aktuelle Sitzung eine neue Sitzung ist. Anschließend wird die neue Sitzung vom SessionStateModule initialisiert und das Session_OnStart-Ereignis ausgelöst. |
CreateNewStoreData-Methode |
Verwendet die HttpContext-Instanz der aktuellen Anforderung und den Timeout-Wert der aktuellen Sitzung als Eingabe und gibt ein neues SessionStateStoreData-Objekt mit einem leeren ISessionStateItemCollection-Objekt, einer HttpStaticObjectsCollection-Auflistung und dem angegebenen Timeout-Wert zurück. Die HttpStaticObjectsCollection-Instanz für die ASP.NET-Anwendung kann mit der GetSessionStaticObjects-Methode abgerufen werden. |
SetItemExpireCallback-Methode |
Verwendet ein Delegat als Eingabe, das auf das in der Datei Global.asax definierte Session_OnEnd-Ereignis verweist. Wenn der Sitzungszustandsanbieter das Session_OnEnd-Ereignis unterstützt, wird eine lokale Verknüpfung auf den SessionStateItemExpireCallback-Parameter festgelegt, und die Methode liefert true zurück. Ansonsten gibt die Methode false zurück. |
Beispiel für einen Anbieter
Eine Beispielimplementierung eines benutzerdefinierten Sitzungsdatenspeicher-Anbieters, bei der Sitzungsinformationen in einer Access-Datenbank verwaltet werden, finden Sie unter Beispiel für einen Sitzungszustandsspeicher-Anbieter.
Siehe auch
Konzepte
Beispiel für einen Sitzungszustandsspeicher-Anbieter