2010-03-05 10 views
5

Offensichtlich funktioniert der typische WebForms-Ansatz nicht. Wie verfolgt man einen Benutzer in einer MVC-Welt?Was ist das akzeptierte Muster für die Implementierung von Session in ASP.NET MVC-Sites?

+0

interessiert mich das selbst. Ich persönlich möchte einen Brotkrumen-Pfad behalten, aber ich möchte das nicht in der Abfrage-Zeichenfolge weitergeben. Was genau wollten Sie über den Benutzer verfolgen? –

+1

Was ist "der typische WebForms-Ansatz", der nicht funktioniert? –

Antwort

22

Die Sitzung funktioniert genauso wie in Webforms. Wenn Sie einfache Informationen speichern möchten, verwenden Sie den Cookie zur Formularauthentifizierung. Wenn Sie einen Inhalt des Einkaufswagens speichern möchten, ist Session der richtige Ort. Ich schrieb einen Blog-Eintrag über using Session with ASP.NET:

Lassen Sie uns sagen, dass wir eine Integer-Variable in Session.We Wrapper erstellen speichern wollen um von Session-Variablen, die es schöner aussehen lässt:

Zuerst definieren wir Schnittstelle:

public interface ISessionWrapper 
{ 
    int SomeInteger { get; set; } 
} 

Dann machen wir Httpcontext Umsetzung:

public class HttpContextSessionWrapper : ISessionWrapper 
{ 
    private T GetFromSession<T>(string key) 
    { 
     return (T) HttpContext.Current.Session[key]; 
    } 

    private void SetInSession(string key, object value) 
    { 
     HttpContext.Current.Session[key] = value; 
    } 

    public int SomeInteger 
    { 
     get { return GetFromSession<int>("SomeInteger"); } 
     set { SetInSession("SomeInteger", value); } 
    } 
} 

GetFromSession und SetInSession sind Helfer-Methode, die Einnahme und s machen Daten in Session einfacher anpassen. SomeInteger-Eigenschaft verwendet diese Methoden.

Dann definieren wir unsere Basis-Controller (für ASP.NET MVC):

public class BaseController : Controller 
{ 
    public ISessionWrapper SessionWrapper { get; set; } 

    public BaseController() 
    { 
     SessionWrapper = new HttpContextSessionWrapper(); 
    } 
} 

Wenn Sie Session außerhalb Controller verwenden möchten, die Sie gerade erstellen oder neue HttpContextSessionWrapper() injizieren.

Sie können SessionWrapper durch ISessionWrapper Mock in Controller-Tests ersetzen, so dass es nicht mehr von HttpContext abhängig ist. Die Sitzung ist auch einfacher zu verwenden, weil Sie SessionWrapper.SomeInteger aufrufen, anstatt (int) Session ["SomeInteger"] aufzurufen. Es sieht schöner aus, oder?

Sie könnten versucht sein, eine statische Klasse zu erstellen, die das Session-Objekt abdeckt und in BaseController keine Schnittstellen oder Initialisierungen definieren muss, aber einige Vorteile verliert, insbesondere beim Testen und Ersetzen durch andere Implementierungen . Hier

+0

Warum würden Sie eine Schnittstelle und eine Wrapper-Klasse schreiben, wenn das Framework bereits 'HttpContext.Current.Session [key]'? –

+8

Weil: 1. var cart = (Liste ) HttpContext.Current.Session [Schlüssel] sieht scheußlich und SessionWrapper.CartItems sieht nett aus. 2. Es ist einfacher, Test für ISessionWrapper zu schreiben. ISessionWrapper kann leicht für verschiedene Testszenarien mit Inhalten nachgeahmt und ersetzt werden. 3. Es verliert Abhängigkeit. Wenn ich einen anderen Speicher anstelle von Session verwenden möchte, erstelle ich einfach eine andere ISessionWrapper-Implementierung. Sie müssen den Code in jedem Controller ersetzen, der Session verwendet. – LukLed

+0

gute Punkte. Obwohl ich den Downvote nicht zurücknehmen kann, wenn du den Post nicht editiert hast. –

2

ist ein Code, den ich verwende, nur ein bisschen „verbesserte“ Version der oben Version:

private T GetFromSessionStruct<T>(string key, T defaultValue = default(T)) where T : struct 
{ 
    object obj = HttpContext.Current.Session[key]; 
    if (obj == null) 
    { 
     return defaultValue; 
    } 
    return (T)obj; 
} 

private T GetFromSession<T>(string key) where T : class 
{ 
    object obj = HttpContext.Current.Session[key]; 
    return (T)obj; 
} 

private T GetFromSessionOrDefault<T>(string key, T defaultValue = null) where T : class 
{ 
    object obj = HttpContext.Current.Session[key]; 
    if (obj == null) 
    { 
     return defaultValue ?? default(T); 
    } 
    return (T)obj; 
} 

private void SetInSession<T>(string key, T value) 
{ 
    if (value == null) 
    { 
     HttpContext.Current.Session.Remove(key); 
    } 
    else 
    { 
     HttpContext.Current.Session[key] = value; 
    } 
} 
+0

Wie würden Sie implementieren, können Sie uns einige Beispiele für den obigen Code zeigen –

Verwandte Themen