Freigeben über


Sitzungszustand

ASP.NET stellt die für Webanwendungen erforderliche, anforderungsübergreifende Infrastruktur mit Zustandsinformationen (Einkaufswagen, Datenbildlauf usw.) bereit. Sie bietet integrierte Funktionen zur Verwaltung des Sitzungszustands und ermöglicht folgende Aktionen:

  • Automatisches Identifizieren und Klassifizieren von Anforderungen eines einzelnen Browserclients in eine logische Anwendungssitzung auf dem Server.

  • Speichern von Daten im Gültigkeitsbereich der Sitzung zur übergreifenden Verwendung für mehrere Browseranforderungen.

  • Auslösen der geeigneten Verwaltungsereignisse (Session_OnStart, Session_OnEnd usw.) während der Lebensdauer der Sitzung, die im Anwendungscode behandelt werden können.

    Hinweis   Das Session_OnEnd-Ereignis wird nur im prozessinternen Sitzungsstatusmodus unterstützt. Dieses Ereignis wird nicht ausgelöst, wenn Sie State Server- oder SQL Server-Modi verwenden.

  • Automatisches Freigeben von Sitzungsdaten, wenn eine Anwendung innerhalb eines festgelegten Zeitlimits nicht erneut vom Browser angesprochen wird.

Dieses Thema bietet eine Übersicht über den Sitzungszustand. Es beschreibt, wie aktive ASP.NET-Sitzungen identifiziert und nachverfolgt werden, erläutert die Speicherstruktur sowie die allgemeine Struktur des Sitzungszustands und schließt mit einem fortgeschrittenen Codebeispiel ab.

Übersicht über den Sitzungszustand

HTTP bildet ein "zustandsloses" Protokoll. Das bedeutet, dass in HTTP nicht automatisch angegeben wird, ob eine Anforderungssequenz vollständig vom selben Client stammt oder ob eine Seite oder Site durchgehend und aktiv über dieselbe Clientinstanz angezeigt wird. Daher kann der Aufbau von Webanwendungen, die anforderungsübergreifende Zustandsinformationen (Einkaufswagen, Datenbildlauf usw.) verwalten müssen, ohne zusätzliche Unterstützung durch die geeignete Infrastruktur zu einer wirklichen Herausforderung werden.

ASP.NET bietet folgende Unterstützung für Sitzungen:

  • Eine benutzerfreundliche Sitzungszustandsfunktion, die ASP-Entwicklern bereits geläufig und mit anderen .NET Framework-APIs kompatibel ist.
  • Eine weitere zuverlässige Sitzungszustandsfunktion, die auch bei Neustarts von Internet-Informationsdiensten (IIS) und Arbeitsprozessen in der Lage ist, Sitzungsdaten beizubehalten.
  • Eine skalierbare Sitzungszustandsfunktion, die sowohl in Webfarmszenarien (mehrere Computer) als auch in Webgartenszenarien (mehrere Prozesse) verwendet werden kann und Administratoren die Möglichkeit bietet, einer Webanwendung mehr Prozessoren zuzuordnen, um ihre Skalierbarkeit zu verbessern.
  • Eine Sitzungszustandsfunktion zur Unterstützung von Browsern, die keine HTTP-Cookies unterstützen.
  • Einen mit ASP vergleichbaren (oder besseren) Durchsatz für die wichtigsten Sitzungszustandsszenarien (Lese-/Schreiboperationen im Verhältnis 50:50 beim Ablegen von Artikeln in Einkaufswagen, Ändern der zuletzt besuchten Seite, Überprüfen von Kreditkartenangaben usw.).

Der Sitzungsstatus bleibt jedoch nicht über Webanwendungsgrenzen erhalten. Wenn eine Webanwendung während der Ausführung zu einer anderen Anwendung wechselt, stehen die Sitzungsinformationen der neuen Anwendung nicht zur Verfügung.

Identifizieren einer Sitzung

Jede aktive ASP.NET-Sitzung wird mit Hilfe einer SessionID-Zeichenfolge von 120 Bits identifiziert und nachverfolgt, die lediglich die in URLs zulässigen ASCII-Zeichen enthält. SessionID-Werte werden mit einem Algorithmus erstellt, der Folgendes garantiert: Die Werte sind eindeutig, so dass keine Sitzungskonflikte entstehen, und sie werden nach dem Zufallsprinzip ausgewählt, so dass eine neue SessionID nicht von einem Benutzer mit unlauteren Absichten dazu verwendet werden kann, die SessionID einer vorhandenen Sitzung zu berechnen.

Die SessionID-Zeichenfolgen werden, abhängig von der Konfiguration der Anwendungseinstellungen, entweder durch ein HTTP-Cookie oder einen geänderten URL mit eingebetteter SessionID-Zeichenfolge übergreifend über Client/Server-Anforderungen übertragen.

Speichern des Sitzungszustands

ASP.NET stellt ein einfaches, benutzerfreundliches Sitzungszustandsmodell bereit, mit dem beliebige Daten und Objekte übergreifend über mehrere Webanforderungen gespeichert werden können. Die Grundlage hierfür bildet ein wörterbuchbasierter, speicherinterner Cache mit Objektverweisen, die sich innerhalb des IIS-Prozesses befinden. Beachten Sie beim Verwenden des prozessinternen Sitzungsstatusmodus die folgenden Einschränkungen:

  • Beim Verwenden des prozessinternen Sitzungsstatusmodus gehen Sitzungsstatusdaten verloren, wenn aspnet_wp.exe oder die Anwendungsdomäne neu gestartet wird. Derartige Neustarts treten i. d. R. unter folgenden Umständen auf:
    • Im <processModel>-Element der Datei Web.config der Anwendung ist ein Attribut festgelegt, durch das ein neuer Prozess gestartet wird, wenn eine Bedingung wie memoryLimit erfüllt ist.
    • Die Datei Global.asax oder Web.config wird geändert.
    • Änderungen am Verzeichnis \Bin der Webanwendung.
    • Die Datei Global.asax, Web.config oder eine Datei im Verzeichnis \Bin der Webanwendung wird durch Antivirensoftware gescannt und verändert.    
  • Verwenden Sie den prozessinternen Sitzungsstatusmodus nicht, wenn Sie den Modus "Webgarten" im <processModel>-Element der Datei Web.config der Anwendung aktivieren. Andernsfalls kann es zu zufälligem Datenverlust kommen.

Anstatt aktive Objekte im prozessexternen Modus zu verwalten, speichert der .NET-Statusserver den Sitzungszustand einfach im Arbeitsspeicher. In diesem Modus kann der Workerprozess direkt mit dem Statusserver kommunizieren. Im SQL-Modus werden Sitzungszustände in einer SQL Server-Datenbank gespeichert, und der Workerprozess kommuniziert direkt mit SQL. Die ASP.NET-Workerprozesse sind dann in der Lage, die Vorteile dieses einfachen Speicherdienstes zu nutzen, indem alle Objekte innerhalb der Session-Auflistung eines Clients am Ende jeder Webanforderung (mit Hilfe von .NET-Serialisierungsdiensten) serialisiert und gespeichert werden. Wenn der Server erneut vom Client angesprochen wird, ruft der entsprechende ASP.NET-Workerprozess diese Objekte als Binärstreams vom Statusserver ab, deserialisiert sie in aktive Instanzen und fügt sie wieder in ein neues Session-Auflistungsobjekt ein, das dem Anforderungshandler zur Verfügung gestellt wird.

Im SQL-Modus kann der Sitzungsstatus auch so konfiguriert werden, dass er in einem Failovercluster funktioniert. Ein Failovercluster besteht aus zwei oder mehr identischen, redundanten Webservern, deren Sitzungsdaten auf einem separaten Computer in einer SQL Server-Datenbank gespeichert werden. Informationen über das Einrichten dieser Konfiguration finden Sie unter Konfigurieren des SQL Server-Modus.

Indem die Speicherung von Sitzungsdaten streng von der Verwendung der Daten durch die Anwendung getrennt wird, unterstützt ASP.NET mehrere leistungsfähige Szenarien, die in früheren Versionen von ASP nicht genutzt werden konnten:

  • Wiederherstellung nach Programmabstürzen, da sich der für den Sitzungszustand verwendete Speicherbereich außerhalb des ASP.NET-Workerprozesses befindet.

    Da sämtliche Zustandsdaten vom jeweiligen Workerprozess getrennt gespeichert werden, bleiben sie erhalten, wenn der Prozess aufgrund einer Zugriffsverletzung abstürzt oder sein Neustart aufgrund eines Deadlocks oder Speicherverlusts vom IIS-Verwaltungsdienst erzwungen wird.

  • Partitionieren einer Anwendung über mehrere Workerprozesse.

    Da alle Zustandsdaten getrennt von Workerprozessen gespeichert werden, kann eine Anwendung problemlos über mehrere Prozesse verteilt werden. Durch eine solche Partitionierung kann sowohl die Verfügbarkeit als auch die Skalierbarkeit einer Anwendung auf Computern mit mehreren Prozessen erheblich verbessert werden. Da jeder Workerprozess in ASP.NET mit einem einzelnen Computer verknüpft wird, können prozessorübergreifende Sperrenkonflikte – in früheren ASP-Versionen eines der größten Hemmnisse für die Skalierbarkeit – eliminiert werden.

  • Partitionieren einer Anwendung über mehrere Webfarmcomputer.

    Da alle Zustandsdaten getrennt von Workerprozessen gespeichert werden, kann eine Anwendung über mehrere, auf unterschiedlichen Computern ausgeführte Workerprozesse verteilt werden. Das Kommunikationsmodell für die Übertragung von Zustandsinformationen zwischen Workerprozessen und Statusdiensten, die auf unterschiedlichen Computern ausgeführt werden, entspricht weitestgehend dem für Prozesse und Server, die auf demselben Computer ausgeführt werden. In beiden Fällen kann nur ein Statusserver pro Webfarm vorhanden sein.

Struktur des Sitzungszustands

ASP.NET-basierte Anwendungen organisieren die Ausführung auf der Basis von Ereignissen. Auf diese Weise können mehrere .NET Framework-Klassenmodule an der Verarbeitung einer einzelnen Webanforderung beteiligt sein.

SessionState-Modul

In .NET Framework wird der Sitzungszustand durch die SessionStateModule-Klasse (die von IHttpModule abgeleitet ist) implementiert, die an der Ausführung jeder Anforderung beteiligt ist, die von einer .NET-basierten Anwendung empfangen wird. Das SessionStateModule ist entweder für das Erstellen oder für das Abrufen eindeutiger SessionID-Zeichenfolgen sowie für das Speichern und Abrufen von Zustandsdaten von einem externen Zustandsprovider verantwortlich.

Sitzungszustandsauflistungen

Die SessionState-Klasse stellt zwei Zustandsauflistungen bereit: Contents und StaticObjects. Durch die Contents-Auflistung werden alle Variablenelemente zur Verfügung gestellt, die der Sitzungszustandsauflistung direkt über den Code hinzugefügt wurden. Beispiel:

' Visual Basic code from within a page, a handler, or Global.asax.
Session("Message") = "MyMsg"
Session("AppStartTime") = Now
[C#]
// C# code from within a page, a handler, or Global.asax.
Session["Message"] = "MyMsg";
Session["AppStartTime"] = DateTime.Now;

Um Kompatibilität mit früheren ASP-Versionen zu gewährleisten, kann auf diese Werte auch mit der Contents-Eigenschaft des Anwendungsobjekts zugegriffen werden, wie im folgenden Beispiel dargestellt.

' Visual Basic code from within a page, a handler, or Global.asax.
Session.Contents("Message") = "MyMsg"
Session.Contents("AppStartTime") = Now
[C#]
// C# code from within a page, a handler, or Global.asax.
Session.Contents["Message"] = "MyMsg";
Session.Contents["AppStartTime"] = DateTime.Now;

Die StaticObjects-Auflistung stellt alle Variablenelemente bereit, die der Sitzungszustandsauflistung über <object runat="server">-Tags innerhalb des Gültigkeitsbereichs von Session in der Datei Global.asax hinzugefügt wurden. Beispiel:

' Global.asax definition.
<OBJECT RUNAT="SERVER" SCOPE="SESSION" ID="MyInfo" PROGID="Scripting.Dictionary">
</OBJECT>

Objekte können der StaticObjects-Auflistung nur aus einer ASP.NET-Anwendung heraus hinzugefügt werden. Wenn ein Benutzer versucht, Objekte direkt über den Code hinzuzufügen, wird eine NotSupportedException-Ausnahme ausgelöst.

Hinweis   Der ASP.NET-Seitencompiler fügt beim Kompilieren der Seite automatisch Memberverweise in alle Objekte ein, die in der StaticObjects-Auflistung gespeichert sind.

Wenn eine Seite angefordert wird, kann der Seitenentwickler direkt auf die Session-Objekte zugreifen, ohne dass die StaticObjects-Auflistung durchlaufen werden muss, wie im folgenden Beispiel gezeigt:

<html>
   </body>
      Number of entries: <%= MyInfo.Count %>
   <body>
</html>

Konfigurieren und Initiieren des Sitzungszustands

In ASP.NET sind drei Sitzungsstatusmodi verfügbar. Sie können zwischen dem prozessinternen Modus, dem Statusserver- und dem SQL Server-Modus wählen. Unabhängig vom ausgewählten Modus ist das grundlegende Konfigurationsverfahren dasselbe.

ASP.NET konfiguriert den Sitzungszustand in zwei Stufen. Zunächst wird das Sitzungszustandsmodul in die HTTP-Anforderung eingefügt. Das Modul wird standardmäßig auf oberster Ebene der Konfigurationshierarchie in der systemweiten Datei Machine.config eingefügt.

Das folgende Beispiel veranschaulicht einen beispielhaften Eintrag in der Datei Machine.config. Damit die Konfigurationsdatei ordnungsgemäß funktioniert, müssen Sie den voll gekennzeichneten Assemblynamen in der richtigen Version der System.Web.SessionState.SessionStateModule-Assembly bereitstellen. Das ist i. d. R. die Version, die der von der Anwendung verwendeten .NET Framework-Version zugeordnet ist. Informationen über das Auffinden des voll gekennzeichneten Assemblynamens finden Sie unter Assemblynamen.

<httpmodules>
   ...
    <!-- You must supply a valid fully qualified assembly name here. -->
    <!-- For this example to work correctly, the version number for -->
    <!-- the referenced assemby must match the version installed on -->
    <!-- your computer by the .NET Framework. -->
    <add name="sessionState" type="System.Web.SessionState.SessionStateModule, Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" />
   ...
</httpmodules>

Legen Sie dann je nach verwendetm Sitzungsstatusmodus die entsprechenden Sitzungsstatusdienstattribute im <sessionState>-Konfigurationselement fest.

Konfigurieren des prozessinternen Modus

Der prozessinterne Modus ist der Standardmodus für den Sitzungsstatus. Für die Verwendung des prozessinternen Modus legen Sie das mode-Attribut des <sessionState>-Elements auf Inproc fest.

Im Folgenden wird beispielhaft eine Konfigurationseinstellung für den prozessinternen Modus dargestellt.

<configuration>
    <system.web>
        <sessionState mode="Inproc"
                      cookieless="false"
                      timeout="20"/>
        </sessionState>
    </system.web>
</configuration>

Konfigurieren des Statusserver-Modus

Um den Statusserver verwenden zu können, müssen Sie zunächst sicherstellen, dass der ASP.NET-Statusdienst auf dem Remoteserver ausgeführt wird, der zum Speichern des Sitzungszustands verwendet wird. Dieser Dienst wird mit ASP.NET und Visual Studio .NET an folgendem Speicherort installiert:

systemroot\Microsoft.NET\Framework\Versionsnummer\aspnet_state.exe

Legen Sie als Nächstes das mode-Attribut des <sessionState>-Elements in der Datei Web.config der Anwendung auf StateServer fest. Legen Sie schließlich das connectionString-Attribut auf **tcpip=Servername:**Anschlussnummer fest.

Im Folgenden wird beispielhaft eine Konfigurationseinstellung für den Statusserver-Modus dargestellt.

<configuration>
    <system.web>
        <sessionState mode="StateServer"
                      stateConnectionString="tcpip=dataserver:42424"
                      cookieless="false"
                      timeout="20"/>
        </sessionState>
    </system.web>
</configuration>

Konfigurieren des SQL Server-Modus

Für die Verwendung des SQL Server-Modus müssen Sie zuerst entweder InstallSqlState.sql oder InstallPersistSqlState.sql auf dem SQL Server-Computer ausführen, auf dem der Sitzungsstatus gespeichert werden soll. Durch beide Skripte wird eine Datenbank namens ASPState erstellt, die mehrere gespeicherte Prozeduren enthält. Der Unterschied zwischen den Skripts besteht in der Platzierung der ASPStateTempApplications-Tabelle und der ASPStateTempSessions-Tabelle. Das InstallSqlState.sql-Skript fügt diese Tabellen der TempDB-Datenbank hinzu. Hierbei gehen die Sitzungsdaten beim Neustart des Computers verloren. Das InstallPersistSqlState.sql-Skript fügt diese Tabellen hingegen der ASPState-Datenbank hinzu, die Sitzungsdaten auch nach einem Neustart des Computers beibehält.

Beide Skriptdateien werden standardmäßig unter folgendem Pfad installiert:

systemroot\Microsoft.NET\Framework\Versionsnummer

Legen Sie als Nächstes das mode-Attribut des <sessionState>-Elements in der Datei Web.config der Anwendung auf SQLServer fest. Legen Sie schließlich das sqlConnectionString-Attribute auf Integrated Security=SSPI;data source=Servername; fest.

Im Folgenden wird beispielhaft eine Konfigurationseinstellung für den SQL Server-Modus dargestellt.

<configuration>
    <system.web>
        <sessionState mode="SQLServer"
                      sqlConnectionString=" Integrated Security=SSPI;data source=dataserver;"
                      cookieless="false"
                      timeout="20"/>
        </sessionState>
    </system.web>
</configuration>

Im SQL Sever-Modus kann der Sitzungsstatus auch so konfiguriert werden, dass er in einem Failovercluster funktioniert. Ein Failovercluster besteht aus zwei oder mehr identischen, redundanten Webservern, deren Sitzungsdaten auf einem separaten Computer in einer SQL Server-Datenbank gespeichert werden. Wenn ein Webserver ausfällt, kann ein anderer Server im Cluster übernehmen und Anforderungen ohne Sitzungsdatenverlust verarbeiten. Zum Konfigurieren eines Failoverclusters legen Sie das <machinekey>-Element in der Datei Web.config des Webservers auf denselben Wert fest. Legen Sie dann die SQL-Verbindungszeichenfolge des Webservers so fest, dass sie auf die SQL Server-Datenbank auf dem Computer zeigt, auf dem die Sitzungsdaten gespeichert werden.

Fortgeschrittenes Codebeispiel

Das folgende Beispiel zeigt, wie im schreibgeschützten Modus auf vorhandene Sitzungszustandsdaten zugegriffen wird, um dynamisch eine Seite mit Benutzerinformationen und Informationen zu einem persönlichen Aktiendepot zu erstellen.

<%@ Language=VB EnableSessionState=true %>
<html>
   <head>
      <script runat="server">
         Sub Page_Load(ByVal Sender as Object, ByVal E as EventArgs)
              ' Obtain data table of user's personal stock data.
              Dim MyStocks as DataTable
              Dim Stock as DataRow
              MyStocks = _
                 CType(Session("PersonalStockData"), DataTable)
              ' Update HTML output with session values.
              Name.InnerText = Session("FirstName").ToString()
              SpouseVal.InnerText = Session("SpouseName").ToString()
              For Each Stock In MyStocks.Rows
                 StockList.AddItem(Stock("Symbol") & ": " & Stock("Name"))
              Next
         End Sub
      </script>
   </head>
   <body>
      Hi <span id="Name" runat=server/>, your spouse is: <span id="SpouseVal" runat="server"/>.
      Here are the stocks you and your spouse currently own:
      <acme:listbox id="StockList" runat="server">
         <! — List box is dynamically populated from code. -->
      </acme:listbox>
   </body>
</html>
[C#]
<%@ Language=C# EnableSessionState=true %>
<html>
   <head>
      <script runat=server>
         void Page_Load(Object Sender, EventArgs E) {
              // Obtain data table of user's personal stock data.
              DataTable MyStocks =
                 (DataTable)Session["PersonalStockData"];
              // Update HTML output with session values.
              Name.InnerText = Session["FirstName"].ToString();
              SpouseVal.InnerText = Session["SpouseName"].ToString();
              foreach (DataRow Stock in MyStocks.Rows) {
                 StockList.AddItem(Stock["Symbol"] + ": "
                                 + Stock["Name"]);
              }
         }
      </script>
   </head>
   <body>
      Hi <span id="Name" runat="server"/>, your spouse is: <span id="SpouseVal" runat="server"/>.
      Here are the stocks you and your spouse currently own:
      <acme:listbox id="StockList" runat="server">
         <! — List box is dynamically populated from code. -->
      </acme:listbox>
   </body>
</html>

Siehe auch

ASP.NET-Zustandsverwaltung