Frage

Ich wünsche den „Zustand“ von einigen Aktionen zu speichern, wird der Benutzer in einer Reihe von verschiedener ASP.Net webforms durchführt. Was sind meine Möglichkeiten für Staat persistierenden und was sind die Vor / Nachteile jeder Lösung?

Ich habe Session Objekte wurden verwendet und einige Helfer Methoden zu stark die Objekte des Typs:

    public static Account GetCurrentAccount(HttpSessionState session)
    {
        return (Account)session[ACCOUNT];
    }

    public static void SetCurrentAccount(Account obj, HttpSessionState session)
    {
        session[ACCOUNT] = obj;
    }

Ich habe von zahlreichen Quellen gesagt, dass „Session böse ist“, so dass wirklich die Ursache für diese Frage ist. Ich will wissen, was Sie denken, „best practice“, und warum.

War es hilfreich?

Lösung

Es gibt nichts von Natur aus böse mit Sitzungszustand.

Es gibt ein paar Dinge im Auge zu behalten, dass Sie könnte allerdings beißen:

  1. Wenn der Benutzer den Browser zurück Taste drückt gehen Sie zurück zur vorherigen Seite, aber Ihr Sitzungsstatus wird nicht rückgängig gemacht. Also Ihr CurrentAccount vielleicht nicht, was es ursprünglich auf der Seite war.
  2. ASP.NET Prozesse können durch IIS recycelt bekommen. Wenn, dass Sie nächste Anforderung geschieht, wird einen neuen Prozess starten. Wenn Sie in dem Prozesssitzungsstatus verwenden, die standardmäßig wird es verschwunden sein: - (
  3. Session kann auch mit dem gleichen Ergebnis Timeout, wenn der Benutzer nicht aktiv seit einiger Zeit ist. Der Standardwert ist 20 Minuten so ein schönes Mittagessen wird es tun.
  4. Verwenden von Process-Sitzungszustands aus, dass alle in dem Sitzungszustand gespeicherten Objekte serialisierbar sein.
  5. Wenn der Benutzer ein zweites Browserfenster öffnet erwarten, dass er eine zweite und unterschiedliche Anwendung haben, aber der Sitzungszustand wird höchstwahrscheinlich zwischen zwei geteilt gehen werden. So ändert die CurrentAccount in einem Browser-Fenster wird das gleiche in den andere tun.

Andere Tipps

Ihre zwei Möglichkeiten zum temporären Formulardaten zu speichern sind, erstens, jede Form der zum Speichern von Informationen in Sitzungszustandsgröße (n) und zweitens entlang über URL-Parameter, die die Form Informationen zu übergeben. Plätzchen als mögliche dritte Option ist einfach nicht praktikabel aus dem einfachen Grund, dass viele Ihrer Besucher wahrscheinlich Cookies ausgeschaltet haben (diese Session-Cookies nicht beeinflussen, jedoch). Auch ich von der Art Ihrer Frage gehe davon aus, dass Sie diese Informationen in einer Datenbanktabelle speichern wollen, bis es vollständig verpflichtet ist.

Verwenden von Session-Variable (n) ist die klassische Lösung für dieses Problem, aber es von einigen Nachteilen leidet. Unter diesen sind (1) große Mengen an Daten können Server RAM verwenden, wenn Sie inproc Session-Management verwenden, (2) Sharing Session-Variablen auf mehrere Server in einer Server-Farm weitere Überlegungen erfordert, und (3) eine professionell gestaltete App muss Schutz vor Sitzungsablauf (nicht nur eine Session-Variable gegossen und es verwenden - wenn die Sitzung den Guss abgelaufen hat, wird einen Fehler melden). Doch für die meisten Anwendungen, Session-Variablen sind zweifellos der Weg zu gehen.

Die Alternative ist, bilden jeweils die Informationen zusammen in der URL zu übergeben. Das primäre Problem bei diesem Ansatz ist, dass man sehr vorsichtig sein muß, werden über „Wegen entlang“ Informationen. Zum Beispiel, wenn Sie Informationen in vier Seiten zu sammeln sind, müßten Sie Informationen in dem ersten sammeln, gibt sie in der URL auf die zweite Seite, wo Sie es in der Seite des Ansichtszustand speichern müssen. Dann, wenn die dritte Seite aufrufen, werden Sie Formulardaten aus der zweiten Seite und den Ansichtszustand Variablen und kodieren sowohl in der URL sammeln, etc. Wenn Sie fünf oder mehr Seiten haben oder wenn der Besucher rund um die Seite springen wird, Sie ‚ll ein echtes Chaos an den Händen haben. Beachten Sie auch, dass alle Informationen zu A benötigt) an eine URL-safe-String und B) in einer solchen Art und Weise codiert serialisiert werden als einfache URL-basierte Hacks zu verhindern (zB wenn Sie den Preis in Klartext setzen und weitergeben entlang, könnte jemand den Preis ändern). Beachten Sie, dass einige dieser Probleme durch die Schaffung einer Art „Sitzungs-Manager“ reduzieren und sie haben zu verwalten, die URL-Strings für Sie, aber Sie würden immer noch extrem empfindlich sein müssen auf die Möglichkeit, dass eine bestimmte Verbindung weg gesamte Sitzung jemand blasen könnte, wenn es ist nicht richtig verwaltet werden.

Am Ende verwende ich URL Variablen nur entlang sehr begrenzte Daten von einer Seite zu der nächsten (z eines Elements ID als auf dieses Element in einer Verbindung codiert) verläuft.

Nehmen wir an, dann, dass Sie tatsächlich die Daten eines Benutzers mit dem eingebauten in Sessions Fähigkeit verwalten würde. Warum würden Sie jemandem sagen, dass „Session böse ist“? Nun, zusätzlich zu der Speicherauslastung, Server-Farm und zum Ablauf von oben dargestellt, die primäre Kritik an der Session-Variablen sind, dass sie effektiv, nicht typisierte Variablen.

Zum Glück, umsichtige Verwendung von Session-Variablen können Speicherprobleme vermeiden (große Gegenstände sollen in der Datenbank ohnehin gehalten werden) und wenn Sie eine Website groß genug laufen eine Serverfarm zu müssen, gibt es viele Mechanismen zur Verfügung Staat teilen gebaut in zu ASP.NET (Hinweis: Sie verwenden inproc Lagerung nicht)

.

Um im Wesentlichen der gesamte Rest der Session die Nachteile zu vermeiden, empfehle ich, dass ein Objekt implementieren Ihre Sitzungsdaten sowie einige einfache Session-Objekt-Management-Funktionen zu halten. Dann bauen diese in einen Nachkommen der Page-Klasse und verwenden diesen Nachkommen Page-Klasse für alle Seiten. Es ist dann eine einfache Sache, Ihre Session-Daten über die Seite Klasse als eine Reihe von stark typisierte Werten zuzugreifen. Beachten Sie, dass Felder Ihre Objekt geben Ihnen einen Weg, jede Ihrer „Session-Variablen“, um in einer stark typisierten Weise (zum Beispiel ein Feld pro Variable).

Lassen Sie mich wissen, ob dies eine einfache Aufgabe für Sie ist oder wenn Sie einige Beispiel-Code möchten!

Soweit ich weiß, Session ist der beabsichtigte Weg, um diese Informationen zu speichern. Bitte beachten Sie, dass Sitzungszustand im Allgemeinen in dem Prozess standardmäßig gespeichert. Wenn Sie mehr Web-Server haben, oder wenn es ein IIS Neustart ist, verlieren Sie den Sitzungszustand. Dies kann durch die Verwendung eines ASP.NET-Statusdienst oder sogar eine SQL-Datenbank festgelegt werden Sitzungen zu speichern. Dadurch wird sichergestellt, Menschen bekommen ihre Sitzung zurück, auch wenn sie auf einen anderen Web-Server umgeleitet werden, oder im Fall einer Rückführung des Arbeitsprozesses.

Einer der Gründe für seinen unheimlichen Ruf ist, dass eiliger Entwickler Übernutzung es mit Stringliterale in UI-Code (statt einer Hilfsklasse wie das Ihre) als Element Tasten und mit einer großen Tasche von untestable Promiscuous Zustand enden. Eine Art Wrapper ist eine Entry-Level-Anforderung für nicht-böse-Sitzung verwenden.

Wie bei „Session ist böse“ ... wenn Sie in klassischen ASP zu entwickeln wäre, würde ich zustimmen müssen, aber ASP.NET/IIS hat eine viel bessere Arbeit.

Die eigentliche Frage ist, was der beste Weg ist, Zustand zu halten. In unserem Fall, wenn es um den aktuellen angemeldeten Benutzer kommt, speichern wir dieses Objekt in der Sitzung, wie wir sind ständig die sich auf sie für ihren Namen, E-Mail-Adresse, Autorisierung und so weiter.

Andere kleine tidbits von Informationen, die keine Ausdauer langfristige braucht man eine Kombination von Cookies und Ansichtszustand verwendet werden.

Wenn Sie Informationen speichern möchten, die global in Ihrer Web-Anwendung zugegriffen werden kann, eine Möglichkeit, dies zu tun, ist das ThreadStatic Attribut. Dadurch wird ein static Mitglied eines Class in ein Element, das durch den aktuellen Thread freigegeben ist, aber keine andere Threads. Der Vorteil ThreadStatic ist, dass Sie nicht zur Verfügung einen Web-Kontext haben müssen. Zum Beispiel, wenn Sie ein hinteres Ende haben, die nicht System.Web referenziert, sondern wollen Informationen auch dort teilen, können Sie die Benutzer id zu Beginn jeder Anfrage in der ThreadStatic Eigenschaft festgelegt, und es in der Abhängigkeit, ohne die Notwendigkeit verweisen der Zugang zu dem Session Objekt.

Weil es static aber nur zu einem einzigen Thread ist, stellen wir sicher, dass andere gleichzeitige Besucher nicht bekommen unsere Sitzung. Dies funktioniert, solange Sie sicherstellen, dass die Eigenschaft für jede Anforderung zurückgesetzt wird. Dies macht es zu einem idealen Begleiter zu Cookies.

Ich denke, mit Session-Objekt ist in diesem Fall in Ordnung, aber Sie sollten Session erinnern kann verfallen, wenn es keine Browser-Aktivität für lange Zeit (

Kurzfristige Informationen, die nur bis zur nächsten Anforderung zum Leben braucht, können auch in der ViewState gespeichert werden. Dies bedeutet, dass Objekte werden serialisiert und in der Seite an den Browser gesendet gespeichert, die dann wieder auf den Server auf einem Click-Ereignisse oder ähnlichem gebucht wird. Dann wird die ViewState dekodiert und verwandelte sich in Objekte wieder bereit abgerufen werden.

Sitzungen sind nicht böse, sie eine wichtige Funktion in ASP.NET-Anwendung dienen, Daten dienen, die von mehreren Seiten während eines Benutzers „Sitzung“ geteilt werden muss. Es gibt einige Vorschläge, würde ich sagen, SQL Session-Management zu verwenden, wenn immer es möglich ist, und stellen sicher, dass die Objekte, die Sie in Ihrer Sitzung Sammlung verwenden sind „serializable“. Die Best Practices wäre das Sitzungsobjekt zu verwenden, wenn Sie unbedingt benötigen Statusinformationen über mehrere Seiten zu teilen, und verwenden Sie es nicht, wenn Sie nicht brauchen. Die Informationen sind nicht verfügbar Client-Seite sein werden, wird ein Sitzungsschlüssel gehalten entweder in einem Cookie, oder durch die Query-String oder andere Methoden verwenden, je nachdem wie es konfiguriert ist, und dann sind die Sitzungsobjekte in der Datenbank-Tabelle zur Verfügung ( es sei denn, Sie InProc verwenden, wobei in diesem Fall Ihre Sitzungen während eines erneuten Laden der Seite die Chance weggeblasen wird, oder werden gerendert fast nutzlos in den meisten Clusterumgebungen) haben wird.

Ich denke, die „böse“ kommt aus über mit der Sitzung. Wenn Sie nur in ihm alles und alles halten (wie globale Variablen für alles verwenden) werden Sie eine schlechte Leistung und nur ein Chaos am Ende mit.

Alles, was Sie in der Sitzungsobjekt gesetzt bleibt dort für die Dauer der Sitzung, es sei denn es gereinigt wird. Schlechte Verwaltung gespeicherter Speicher mit inproc und State wird Sie zwingen, früher zu skalieren als nötig. Speichern Sie nur eine ID für die Sitzung / Benutzer in der Sitzung und laden, was in das Cache-Objekt auf Nachfrage benötigt wird, eine Hilfsklasse verwenden. Auf diese Weise kann die Feinabstimmung kann es Lebensdauer je nachdem, wie oft die Daten wir verwendet. Die nächste Version von asp.net kann einen verteilten Cache (Gerücht).

Session als böse: Nicht in ASP.NET, richtig konfiguriert ist. Ja, es ist ideal wie möglich als staatenlos zu sein, aber die Realität ist, dass Sie nicht da von hier bekommen. Sie können jedoch machen Session in einer Weise verhalten, die ihre Auswirkungen verringern -. Bemerkenswerterstate oder Datenbanksitzungen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top