Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Dies ist die Fortsetzung der Artikelserie "ASP.NET Grundlagen" mit folgenden Teilen:

In Teil 1 gab es einen Blick hinter die Kulissen und die Erkenntnis das es der Entwickler bei Webtechnologien mit Statuslosigkeit zu tun hat.

Es gibt jedoch Möglichkeiten um die Statuslosigkeit mehr oder weniger loszuwerden bzw. mit der Statuslosigkeit umzugehen.
Auf diese Möglichkeiten möchte ich jetzt eingehen, vorallem wann / wie / was genutzt werden kann oder sollte.

SessionState

Der SessionState bietet die Möglichkeit Benutzer über eine Sitzung weg zu identifizieren.
Dies geschieht mit der Nutzung eines temporären Cookies auf dem Computer des Benutzers,
in diesem Cookie ist eine SessionId - eine Id zur Identifikation des Benutzers am Server - gespeichert.

Die Session bleibt solange bestehen, bis das Timeout nach dem letzten Kontakt mit dem Server abgelaufen ist, oder aber das Browserfenster geschlossen wird.
Anmerkung:
Wenn das Browserfenster geschlossen wird, ist die Session clientseitig verloren, serverseitig läuft sie aber noch solange bis der Timeout abgelaufen ist. Benutzt werden kann sie nicht mehr -> Ausser bei speziellen Spezialfällen natürlich....

Anhand der SessionId können dann Daten im Arbeitsspeicher des Servers für einen Benutzer gespeichert und abgerufen werden.

Benutzt wird / sollte der SessionState primär für alles was im Benutzerkontext abläuft.
Allerdings reicht es auch hier in den meisten Fällen, bzw. ist es ratsam nur jeweils eine Identifizierung (Bentzer-Id in der Datenbank) in der Session zu speichern, da pro Benutzer gespeichert wird.

Das bedeutet - bei einer Mehrbenutzeranwendung -was ASP.NET auch ist, dass pro Benutzer jeweils Objekte im Arbeitsspeicher des Servers gehalten werden.
Diese bleiben solange im Arbeitsspeicher vorhanden, bis das Session-Timout abläuft oder aber die Daten manuell gelöscht werden.

Darum sollte darauf darauf geachtet werden, dass nur wirklich die nötigsten Daten im SessionState gehalten werden.

Nehmen wir bspw. mal eine Datenmenge von 500Kb die sich bei jedem Nutzer der Webanwendung angesammelt wird, dies bei 100 Benutzern.
500 x 100 = 50'000Kb = 50Mb. (1000Kb oder 1024Kb mal aussen vor gelassen).

Wenn während dem Timeout (Standardmässig 20 Minuten) nochmals 50 Benutzer hinzukommen, beläuft sich die Menge des benutzen Arbeitsspeicher schon auf 75Mb.

Wenn die Session-Daten im Arbeitsspeicher des Servers gehalten werden, nennt sich der Modus "InProc" (In Process), es gibt auch die Möglichkeit einen StateServer, SqlServer oder eine eigene Implementation zu verwenden um die Session-Daten auch über die Lebenszeit der Applikation zu behalten.

Cookie

Im Gegensatz zum SessionState bleiben Cookies bis zu einem gesetzten Ablaufdatum bestehen und die Daten werden auf dem Client und nicht auf dem Server gespeichert.
Das ist nütztlich um eine Funktion àla "Daten merken?" zu implementieren.

Der SessionState (temporäre Cookies) und Cookies schliessen sich also nicht nicht gegenseitig aus, sondern ergänzen sich.
So kann dieselbe Funktionalität mit dem SessionState gelöst werden und Cookies kommen dann zum Spiel, wenn die Einstellungen / Login dauerhaft, auch über eine Browsersitzung / Timout hinaus genutzt werden möchte.

Datenbank

Auch in Zusammenarbeit mit dem SessionState oder Cookies kann eine Datenbank benutzt werden, um einen Status abzuspeichern.
Der SessionState / Cookies sorgen für die Identifizierung des Benutzers und die Datenbank fungiert als Speicher.

Diese beiden Systeme (bspw. Cookie und Datenbank) assoziieren sich jeweils mit einer eindeutigen ID, sodass ein Status wiederhergestellt werden kann.

Cache

Mithilfe des Caches können Daten (Bspw. von aufwändigen Anforderungen wie die eines WebRequests oder einer langsamen Datenbankabfrage) zwischengespeichert werden, um die Anwendung zu beschleunigen.
In ASP.NET ist ausserdem das Feature "Output Cache" eingebaut, dass die aktuelle Ausgabe einer Anforderung (Bsw. einer ASP.NET Seite) zwischengespeichert werden kann.
Diese Zwischenspeicherung gilt dann (Wie auch beim normalen Cache) solange bis eine Abhängigkeit (CacheDependency) nicht mehr gültig ist.
Das kann eine Zeitdauer sein, eine Änderung einer lokalen Datei - eines Verzeichnisses oder aber etwas völlig anders (VaryByCustom oder eine eigene Abhängigkeit).

So kann bspw. für angemeldete Benutzer jeweils die Seite im Cache mit sensiblen Daten zurückgegeben werden, und bei Gästen diese ohne die sensiblen Daten, aber genauso aus dem Cache.

Ich habe den Cache hier reingenommen, da ich ihn auch für ein sehr wichtiges Mittel halte, es geht hier nicht wirklich um den Status von Client / Server sondern um die Art, Daten zwischenzuspeichern.

Application Items oder statische Variabeln

Applikationsweit _für alle Benutzer gleich_ (Siehe: Statische Variablen in ASP.NET) können Daten in der Applikations-Items-Auflistung oder - läuft im gleichen Kontext - als statische Variablen gehalten werden.

Hier ist jedoch Vorsicht geboten und die Daten gehen nach einem Applikations-Neustart wieder verloren.
Auch wird hier der Arbeitsspeicher des Servers als Medium benutzt, daher sollte auch mit der Menge der Daten sparsam umgegangen werden. (Wink an Jürgen ;-)

Andere persistente Medien (Harddisk, Textdatei, ...)

Genau so wie bei der Datenbank beschrieben, können auch andere persistente Medien als Status-Speicher benutzt weren.
Seien das jetzt Textdateien, XML-Dateien, CSV-Dateien, ....

ViewState

Das ViewState-Feature das mit ASP.NET eingeführt wurde, ist sowohl alt als auch neu.
ASP.NET benutzt die Tatsache, das viele Aufrufe in ASP.NET standardmässig per POST an den Server gesendet werden,
um aktuelle Statusinformationen in einem Html-Hidden-Field zu speichern und bei der nächsten Anforderung wieder zu lesen.

Dabei lassen sich zwei Kategorien unterscheiden: Der ControlState und der ViewState.
Der Mechanismus ist der selbe, jedoch wird der ControlState nur von WebControls benutzt und kann von einem Seitenentwickler nicht deaktiviert werden.
Der ViewState hingegen wird von ASP.NET selber auf Seitenebene genutzt und kann auch von einem Entwickler auf Seite- sowie Controlebene eingesetzt werden.

Für den View- sowie den ControlState wird jeweils ein seperates HiddenField von ASP.NET generiert und verwendet.

Das war in einer CTP so, Zitat von Jens (Danke für deinen durchaus konstruktiven Kommentar!):

Es gab mal die Variante mit "__CONTROLSTATE" in einer CTP-Version wurd aber in der Finalen Version so nicht realisiert, da dadurch Performance-Einbußen zustande kamen.

Beispielanwendung:
ViewState["key"] = "value";

Mit dieser Zuweisung erfolgt serverseitig eine Speicherung als Schlüssel / Wert-Paar (Key / Value-Pair).
Alle Zuweisungen werden von ASP.NET zu einem String serialisiert und vor dem Zurücksenden des Outputs an den Client in einem versteckten Formularfeld gespeichert.
Bei einer erneuten Anforderng per POST liest ASP.NET die Werte wieder in das Objektmodell und macht sie durch den Entwickler und die Objekte die selber agieren, abruf- und zuweisbar.

Einfach gesagt: Mit Hilfe des ViewState-Mechanismus lassen sich Daten (Besser Stati) über einen PostBack am Leben erhalten.
Jedoch funktioniert das nur solange bis die nächste Anforderung nicht mehr per POST kommt, sondern bspw. per GET.
Bei einer GET-Anforderung: Also beispielsweise einen Klick auf ein Hyperlink, ein serverseitiger Response.Redirect oder einem einfachen Refresh der Seite im Browser (Ohne das mitsenden allfälliger Formulardaten) sind alle Daten im ViewState verloren und auf den Nullzustand zurückgesetzt.

Folgendes zeig dies auf:
POST -> POST -> POST -> POST (Status bleibt die ganze Zeit erhalten)
POST -> POST -> POST -> GET -> POST (Status ist ab der ersten GET-Abfrage zurückgesetzt)

Ich hoffe dass diese Artikel ein wenig Licht ins Dunkle bringen konnte und das Verständnis zu den vorhanden Möglichkeiten stärken.

Bearbeitung / Korrekturen:
15.09.08 - Absatz über den View- und ControlState hinzugefügt (Danke an Golo)
17.09.08 - Hinweis über den ControlState korrigiert (Danke an Jens)

Veröffentlicht Sonntag, 14. September 2008 23:19 von Peter Bucher

Kommentare

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hi Peter,

die beiden Einträge gefallen mir sehr gut, allerdings bin ich bei einem Satz ein wenig skeptisch. Du schreibst:

"Die Session bleibt solange bestehen, bis das Timeout nach dem letzten Kontakt mit dem Server abgelaufen ist, oder aber das Browserfenster geschlossen wird."

Ich halte diese Formulierung für ein wenig irreführend, denn die Session (auf dem Server) läuft nicht in dem Moment ab, wenn das Browserfenster geschlossen wird - dies bemerkt der Server ja überhaupt nicht, außer, dass sich eben nichts mehr tut bei diesem Client.

Ob der Client aber einfach nur Kaffeetrinken gegangen ist, oder sein Fenster geschlossen hat, kann der Server meines Wissens nicht unterscheiden.

Insofern bleibt auch nach dem Schließen des Browsers die Session noch so lange bestehen, bis sie vom Timeout beendet wird.

Dass der Client nicht mehr auf die Session zugreifen kann, steht auf einem anderen Blatt - aber existieren tut sie noch.

Viele Grüße,

Golo

PS: Was mir noch gefehlt hat, war der ViewState ;-).

Montag, 15. September 2008 14:37 by Golo Roden

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Golo

Vielen Dank für deinen Kommentar!

Du hast Recht, das ging wohl in meinem Gedankengang unter das auszuschreiben.

So wäre es besser:

"

[Mein vorheriger Text]

+

Anmerkung:

Wenn das Browserfenster geschlossen wird, ist die Session clientseitig verloren, serverseitig läuft sie aber noch solange bis der Timeout abgelaufen ist. Benutzt werden kann sie nicht mehr.

"

Viewstate... hmm, hab ich das extra weggelassen? ;)

Kommt am Abend noch hinzu, danke für den Hinweis.

Montag, 15. September 2008 15:32 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Perfekt :-)

Montag, 15. September 2008 15:36 by Golo Roden

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Peter,

> Wenn das Browserfenster geschlossen wird, ist die Session clientseitig verloren, serverseitig

> läuft sie aber noch solange bis der Timeout abgelaufen ist. Benutzt werden kann sie nicht

> mehr.

so ist das eigentlich auch nicht richtig. Wenn der Client dasselbe Sessioncookie an den Server sendet, kann er die Session übernehmen. Das Prinzip sieht man bspw. wenn Firefox abstürzt und nach dem nächsten Start wird gefragt, ob die Sitzungen wiederhergestellt werden sollen. In dem Fall wird das Sessioncookie der alten Session wieder gesendet und die Session wird (wenn sie nicht zwischenzeitlich serverseitig abgelaufen ist) wiederverwendet.

Montag, 15. September 2008 15:43 by Stefan Falz

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Stefan

Okay, das ist dann aber ein spezieller Spezialfall.

Im Normalfall ist das clientseitige Sitzungscookie hinüber und somit die serverseitige Sitzung nicht mehr benutzbar (Von schlimmen Dingen mal abgesehen).

Montag, 15. September 2008 16:02 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Update: ViewState-Absatz ergänzt (Danke für den Hinweis Golo).

Montag, 15. September 2008 19:16 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

>>Für den View- sowie den ControlState wird jeweils ein seperates HiddenField von ASP.NET generiert und verwendet.

Soweit ich weis, nutzt der ControlState das gleiche HiddenField wie der ViewState. Auch bei deaktivierten ViewState wird bei Controls die den ControlState benutzten ein ViewState-HiddenField gerendert.

Grüße,

Jens

Dienstag, 16. September 2008 16:46 by JHofmann

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Jens

Danke für deinen Kommentar.

Nein, für den Controlstate gibts das Feld "__CONTROLSTATE".

Bei deaktivierem ViewState wird der ControlState immer mitgerendert, ob das Feld ändert weiss ich nicht, ich denke es aber nicht.

Dienstag, 16. September 2008 17:41 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Mhh, also ich hatte das mal so in einem Buch gelesen und da ich es nicht glauben konnte das ich mich verlesen habe, habe ich jetzt auch nochmal gesucht. Aus der MSDN:

"Control state is designed for storing a control's essential data (such as a pager control's page number) that must be available on postback to enable the control to function even when view state has been disabled. By default, the ASP.NET page framework stores control state in the page in the same hidden element in which it stores view state."

http://msdn.microsoft.com/en-us/library/1whwt1k7.aspx

MSDN falsch? Ich hab aber noch nie das "__CONTROLSTATE"-HiddenField gesehen muss ich sagen.

Grüße,

Jens

Mittwoch, 17. September 2008 09:46 by JHofmann

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Jens

MSDN muss nicht immer richtig sein.

Ich habe mich auf Dino Esposito verlassen :-)

Jedoch kann es gut sein, dass dies nur in einer speziellen ASP.NET Version vorhanden war.

- http://www.google.ch/search?hl=de&q=__controlstate&meta=

Du scheinst also Recht zu haben, auf meiner Seite habe ich den Viewstate auch aus, und es ist trotzem ein __VIEWSTATE-HiddenField vorhanden.

Mittwoch, 17. September 2008 10:14 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hab jetzt mal noch unterschiedliche Blogeinträge durchgesehen. Es gab mal die Variante mit "__CONTROLSTATE" in einer CTP-Version wurd aber in der Finalen Version so nicht realisiert, da dadurch Performance-Einbußen zustande kamen.

Warst also nicht ganz falsch. Ich war halt verwundert, da ich sehr viele Controls geschrieben habe die Controlstate benutzen und noch nie ein "__CONTROLSTATE"-HiddenField  gesehen habe.

Nichts desto trotz, guter Artikel!!!

Grüße,

Jens

Mittwoch, 17. September 2008 10:37 by JHofmann

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Jens

Vielen dank für deine durchaus konstruktive Kritik, ich werde dies gleich ändern.

So hab ichs doch am liebsten :)

Danke auch für dein Lob!

Mittwoch, 17. September 2008 10:52 by Peter Bucher

# Basic Authentication mit ASP.NET

Möglichkeiten der Authentifizierung mit ASP.NET Mit ASP.NET gibt es verschiedene Möglichkeiten,

Freitag, 17. Oktober 2008 14:55 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Hallo Peter,

wollte zu deinen "Browser Spezialfällen" noch anmerken: IE bis 6.0 hat die Session nicht wenn er neu gestartet wird (neuer Prozess, Coockie ist weg), beim Firefox wird immer derselbe Firefox-Prozess angesprochen (Session lebt weiter), IE ab 7.0 hat das Verhalten von FF. Also reicht das "Fenster schliessen" nicht immer. Andere Browser wären imho noch interessant.

:-)

Xynratron

Dienstag, 28. Oktober 2008 00:01 by Xynratron

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Salue Xynraton

Du meinst damit jetzt aber Tabs, oder?

Dort ist das Verhalten anders, aber wenn du Fenster schliesst (Nicht Tabs) ist die Session IMO immer weg - aber mit allen Browsern hab ich das nicht getestet.

Gruss Peter

Dienstag, 28. Oktober 2008 00:19 by Peter Bucher

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

huhu,

Nein, lass die Tabs mal weg. Wenn das ursprüngliche Browserfenster nicht geschlossen wurde: Starte einen neuen Browser per Shortcut über den Desktop: FF + IE7 nutzen den ursprünglichen Prozess und die Cookies aus dem anderen Browser bleiben erhalten.

:-)

Xynratron

Mittwoch, 29. Oktober 2008 20:44 by Xynratron

# re: ASP.NET Grundlagen Teil 2: Tschüss Statuslosigkeit

Huhu :-)

Okay - gut zu wissen - danke!

Freitag, 31. Oktober 2008 14:31 by Peter Bucher

# Facade Pattern und ein Anwendungsbeispiel: SessionFacade

Vor einiger Zeit habe ich über das Strategy-Pattern geschrieben , dort sind auch Links zu der Definition

Dienstag, 9. Dezember 2008 21:50 by Peter Bucher

# ASP.NET und dann war da noch was…

Ach ja. Es gab damals noch so was wie HTML, CSS und JavaScript, aber das ist ja heutzutage blöd, schließlich

Donnerstag, 12. März 2009 15:43 by Jürgen Gutsch
Anonyme Kommentare sind nicht zugelassen