Wie verwende ich Sitzungen in einer ASP.NET MVC 4-Anwendung?

113

Ich bin neu in ASP.NET MVC. Ich habe zuvor PHP verwendet und es war einfach, eine Sitzung zu erstellen und Benutzerdatensätze basierend auf den aktuellen Sitzungsvariablen auszuwählen.

Ich habe überall im Internet nach einer einfachen Schritt-für-Schritt-Anleitung gesucht, die mir zeigt, wie ich Sitzungen in meiner C # ASP.NET MVC 4-Anwendung erstelle und verwende. Ich möchte eine Sitzung mit Benutzervariablen erstellen, auf die ich von überall in meinen Controllern zugreifen kann, und die Variablen in meinen LINQ-Abfragen verwenden können.

Thuto Paul Gaotingwe
quelle
2
Mögliches Duplikat von So pflegen Sie die Benutzersitzung mit ASP.NET MVC
adatapost
2
Dieser Artikel könnte von Interesse sein: brockallen.com/2012/04/07/think-twice-about-using-session-state
Daniel Hollinrake

Antworten:

160

Versuchen

//adding data to session
//assuming the method below will return list of Products

var products=Db.GetProducts();

//Store the products to a session

Session["products"]=products;

//To get what you have stored to a session

var products=Session["products"] as List<Product>;

//to clear the session value

Session["products"]=null;
Jobert Enamno
quelle
3
Danke Jobert! Du hast mir eine Idee gegeben! Ich frage mich nur, ob es möglich ist, einer Sitzung während der Anmeldung Benutzervariablen hinzuzufügen. und habe ich auch Zugriff auf Sitzungsvariablen (nur einmal erstellt) über verschiedene Controller in meiner Anwendung?
Thuto Paul Gaotingwe
31
Sie können beliebige Daten in einer Sitzung speichern. Nach der Erstellung können Sie in allen Ansichten und Controllern auf den darin gespeicherten Wert zugreifen. Beachten Sie auch, dass die erstellte Sitzung nur pro Benutzer und pro Browser zugänglich ist. Dies bedeutet, dass auf die von Benutzer1 mit Firefox erstellte Sitzung nicht mit demselben Benutzer über IE zugegriffen werden kann. Es gibt Dinge, die Sie auch nicht mit Sitzungen tun sollten, wie z. Speichern Sie keine großen Daten darauf. Dies kann die Leistung Ihres Servers beeinträchtigen. Speichern Sie keine sensiblen Daten für eine Sitzung wie Passwort oder Kreditkartennummer
Jobert Enamno
2
Nochmals vielen Dank! Wo erstelle ich es, um über verschiedene Controller darauf zugreifen zu können?
Thuto Paul Gaotingwe
2
@JobertEnamno ist es sicher, den Wert zu speichern, von dem er stammt, WebSecurity.CurrentUserIddamit er nicht mehrmals aus der Datenbank abgerufen wird (ich fand ihn sehr kostspielig)?
Andrius Naruševičius
2
Es gibt keine Controller-übergreifende Sitzung. Wenn Sie also einen anderen Controller anfordern, z. B. von Account/LogOnbis Home/Index, Session["FirstName"]ist null. Entwickler müssen einen übergeordneten Controller ( BaseController) erstellen und ein geschütztes Feld ( internal protected HttpSessionStateBase SharedSession) definieren , das die gemeinsam genutzte Sitzungsvariable in allen BaseController
Subcontrollern
63

Aufgrund der Statuslosigkeit des Webs sind Sitzungen auch eine äußerst nützliche Methode, um Objekte über Anforderungen hinweg zu persistieren, indem sie serialisiert und in einer Sitzung gespeichert werden.

Ein perfekter Anwendungsfall hierfür könnte sein, wenn Sie auf reguläre Informationen in Ihrer Anwendung zugreifen müssen, um zusätzliche Datenbankaufrufe bei jeder Anforderung zu speichern. Diese Daten können in einem Objekt gespeichert und bei jeder Anforderung unserialisiert werden, wie folgt:

Unser wiederverwendbares, serialisierbares Objekt:

[Serializable]
public class UserProfileSessionData
{
    public int UserId { get; set; }

    public string EmailAddress { get; set; }

    public string FullName { get; set; }
}

Anwendungsfall:

public class LoginController : Controller {

    [HttpPost]
    public ActionResult Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            var profileData = new UserProfileSessionData {
                UserId = model.UserId,
                EmailAddress = model.EmailAddress,
                FullName = model.FullName
            }

            this.Session["UserProfile"] = profileData;
        }
    }

    public ActionResult LoggedInStatusMessage()
    {
        var profileData = this.Session["UserProfile"] as UserProfileSessionData;

        /* From here you could output profileData.FullName to a view and
        save yourself unnecessary database calls */
    }

}

Sobald dieses Objekt serialisiert wurde, können wir es auf allen Controllern verwenden, ohne es erstellen oder die Datenbank erneut nach den darin enthaltenen Daten abfragen zu müssen.

Injizieren Sie Ihr Sitzungsobjekt mit Dependency Injection

In einer idealen Welt würden Sie " auf eine Schnittstelle programmieren, nicht implementieren " und Ihr serialisierbares Sitzungsobjekt mithilfe des von Ihnen gewählten Inversion of Control-Containers in Ihren Controller einfügen (in diesem Beispiel wird StructureMap verwendet, wie ich es am besten kenne ).

public class WebsiteRegistry : Registry
{
    public WebsiteRegistry()
    {
        this.For<IUserProfileSessionData>().HybridHttpOrThreadLocalScoped().Use(() => GetUserProfileFromSession());   
    }

    public static IUserProfileSessionData GetUserProfileFromSession()
    {
        var session = HttpContext.Current.Session;
        if (session["UserProfile"] != null)
        {
            return session["UserProfile"] as IUserProfileSessionData;
        }

        /* Create new empty session object */
        session["UserProfile"] = new UserProfileSessionData();

        return session["UserProfile"] as IUserProfileSessionData;
    }
}

Sie würden dies dann in Ihrer Global.asax.csDatei registrieren .

Für diejenigen , die mit dem Einspritzen Sitzungsobjekte nicht vertraut sind, können Sie eine tiefer gehende Blog - Post über das Thema finden Sie hier .

Ein Wort der Warnung:

Es ist erwähnenswert, dass Sitzungen auf ein Minimum beschränkt werden sollten. Große Sitzungen können Leistungsprobleme verursachen.

Es wird auch empfohlen, keine vertraulichen Daten (Kennwörter usw.) darin zu speichern.

Joseph Woodward
quelle
Wo würden Sie die Klassendefinition platzieren? Ich bin noch ziemlich neu in allem, aber ich bin nur neugierig, wie andere Controller die Klasse sehen und wissen, was es ist. Fügen Sie es einfach oben auf dem Controller hinzu? Ich habe über SessionStart in global.asax nachgedacht. Ich würde Dinge initialisieren, aber vielleicht ist das nicht der beste Weg, dies zu tun.
Shaun314
@ Shaun314 Idealerweise verwenden Sie einen IoC-Container, um das Objekt über die Abhängigkeitsinjektion in Ihren Controller zu injizieren (siehe Bearbeiten).
Joseph Woodward
1
Ich speichere einige Sitzungsinformationen, nachdem ich mich mit Identity 2 beim Benutzer angemeldet habe. Ich kann diese Informationen nur in der ersten Aktion abrufen, zu der ich den Benutzer umleitung. Irgendeine Idee?
Akbari
17

So funktioniert der Sitzungsstatus in ASP.NET und ASP.NET MVC:

Übersicht über den ASP.NET-Sitzungsstatus

Grundsätzlich tun Sie dies, um einen Wert im Sitzungsobjekt zu speichern:

Session["FirstName"] = FirstNameTextBox.Text;

So rufen Sie den Wert ab:

var firstName = Session["FirstName"];
Leniel Maccaferri
quelle
10
Es gibt keine Controller-übergreifende Sitzung. Wenn Sie also einen anderen Controller anfordern, z. B. von Accountbis Home, ist Sitzung ["Vorname"] null. Entwickler müssen BaseControllerein geschütztes Feld ( internal protected HttpSessionStateBase SharedSession) erstellen und definieren , das die gemeinsam genutzte SessionVariable in allen BaseController
Subcontrollern
4
Ähm, sicher gibt es das? In Controller gibt es eine Sitzungsvariable (den von MVC bereitgestellten Basis-Controller).
Aeliusd
7
@ Bellash das ist völlig falsch. Sitzungen sind für alle Controller verfügbar. Ich habe gerade die Sitzung ["test"] in HomeController festgelegt und sie dann in meinem AccountController gelesen.
Niico
0

Sie können jede Art von Daten in einer Sitzung speichern, indem Sie:

Session["VariableName"]=value;

Diese Variable dauert ungefähr 20 Minuten.

Ulyses
quelle
-8

Sie können einen beliebigen Wert in einer Sitzung speichern, z. B. Sitzung ["Vorname"] = VornameTextBox.Text; aber ich werde u vorschlagen, als statisches Feld im Modell Wert zuzuweisen, und Sie können auf diesen Feldwert überall in der Anwendung zugreifen. Du brauchst keine Sitzung. Sitzung sollte vermieden werden.

public class Employee
{
   public int UserId { get; set; }
   public string EmailAddress { get; set; }
   public static string FullName { get; set; }
}

auf dem Controller - Employee.FullName = "ABC"; Jetzt können Sie überall in der Anwendung auf diesen vollständigen Namen zugreifen.

Mukul Sharma
quelle
10
Das Speichern von Daten in statischen Feldern, insbesondere von Benutzerdaten wie dem Namen des Mitarbeiters, führt in Mehrbenutzerumgebungen zu schwerwiegenden Problemen. Wenn sich zwei verschiedene Benutzer im System angemeldet haben, wird dieselbe Employee.EmailAddress angezeigt, da das statische Feld für Employee für jede Instanz gleich ist.
Gökçer Gökdal