Come utilizzare le sessioni in un'applicazione ASP.NET MVC 4?


113

Sono nuovo in ASP.NET MVC. Ho già utilizzato PHP in passato ed è stato facile creare una sessione e selezionare i record utente in base alle variabili della sessione corrente.

Ho cercato ovunque su Internet un semplice tutorial passo passo che mi può mostrare come creare e utilizzare sessioni nella mia applicazione C # ASP.NET MVC 4. Desidero creare una sessione con variabili utente a cui posso accedere da qualsiasi posizione nei miei controller ed essere in grado di utilizzare le variabili nelle mie query LINQ.



Risposte:


160

Provare

//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;

3
Grazie Jobert! mi hai dato un'idea! mi chiedo solo però .., è possibile aggiungere variabili utente a una sessione durante il login? e inoltre avrò accesso alle variabili di sessione (create una sola volta) su diversi controller nella mia applicazione?
Thuto Paul Gaotingwe

31
Puoi memorizzare qualsiasi cosa o qualsiasi dato di qualsiasi tipo in una sessione. Una volta creato, puoi accedere al valore memorizzato su tutte le visualizzazioni e i controller. Tieni inoltre presente che la sessione creata è accessibile solo per utente e per browser. Significa che la sessione creata da Utente1 utilizzando Firefox non è accessibile dallo stesso utente utilizzando IE. Ci sono anche cose che non dovresti fare con la sessione come. NON archiviare dati di grandi dimensioni su di esso. Ciò potrebbe rallentare le prestazioni del tuo server. Infine, NON memorizzare dati sensibili in una sessione come password o numero di carta di credito
Jobert Enamno

2
Grazie ancora una volta! Dove lo creo per potervi accedere attraverso diversi controller?
Thuto Paul Gaotingwe

2
@JobertEnamno è sicuro memorizzare il valore da cui proviene in WebSecurity.CurrentUserIdmodo da non estrarlo più volte dal database (ho trovato che è molto costoso)?
Andrius Naruševičius

2
Non esiste una sessione cross controller, quindi quando richiedi un altro controller, ad esempio da Account/LogOna Home/Index, Session["FirstName"]è null. Gli sviluppatori devono creare un controller principale ( BaseController) e definire un campo protetto ( internal protected HttpSessionStateBase SharedSession) che possa esporre la variabile Session condivisa in tutti i controller secondari (questo presuppone che tutti i controller dell'app ereditino da BaseController)
Bellash

63

A causa della natura senza stato del web, le sessioni sono anche un modo estremamente utile per rendere persistenti gli oggetti tra le richieste serializzandoli e memorizzandoli in una sessione.

Un caso d'uso perfetto di questo potrebbe essere se è necessario accedere a informazioni regolari attraverso l'applicazione, per salvare ulteriori chiamate al database su ogni richiesta, questi dati possono essere memorizzati in un oggetto e non serializzati su ogni richiesta, in questo modo:

Il nostro oggetto riutilizzabile e serializzabile:

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

    public string EmailAddress { get; set; }

    public string FullName { get; set; }
}

Caso d'uso:

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 */
    }

}

Una volta che questo oggetto è stato serializzato, possiamo usarlo su tutti i controller senza doverlo creare o interrogare nuovamente il database per i dati in esso contenuti.

Inietta il tuo oggetto sessione utilizzando Dependency Injection

In un mondo ideale dovresti ' programmare su un'interfaccia, non sull'implementazione ' e iniettare il tuo oggetto di sessione serializzabile nel tuo controller usando il tuo contenitore Inversion of Control preferito, in questo modo (questo esempio usa StructureMap poiché è quello con cui ho più familiarità ).

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;
    }
}

Dovresti quindi registrarlo nel tuo Global.asax.csfile.

Per coloro che non hanno familiarità con l'inserimento di oggetti di sessione, è possibile trovare un post di blog più approfondito sull'argomento qui .

Una parola di avvertimento:

Vale la pena notare che le sessioni dovrebbero essere ridotte al minimo, sessioni di grandi dimensioni possono iniziare a causare problemi di prestazioni.

Si consiglia inoltre di non archiviare dati sensibili (password, ecc.).


Ma dove metteresti la definizione della classe? Sono ancora abbastanza nuovo in tutto, ma sono solo curioso di sapere come gli altri controller vedranno la classe e sapranno di cosa si tratta. Lo aggiungi semplicemente nella parte superiore del controller? Stavo pensando a SessionStart in global.asax avrei inizializzato le cose ma forse non è il modo migliore per farlo.
Shaun314

@ Shaun314 Idealmente useresti un contenitore IoC per iniettare l'oggetto nel tuo controller tramite iniezione di dipendenza (vedi modifica).
Joseph Woodward,

1
Sto memorizzando alcune informazioni sulla sessione dopo aver effettuato l'accesso dell'utente utilizzando Identity 2. Non sono in grado di recuperare tali informazioni in altre azioni e controller se non la prima azione a cui reindirizzo l'utente. Qualche idea?
Akbari

17

Ecco come funziona lo stato della sessione in ASP.NET e ASP.NET MVC:

Panoramica dello stato della sessione ASP.NET

Fondamentalmente, fai questo per memorizzare un valore nell'oggetto Session:

Session["FirstName"] = FirstNameTextBox.Text;

Per recuperare il valore:

var firstName = Session["FirstName"];

10
Non esiste una sessione cross controller, quindi quando richiedi un altro controller, ad esempio da Accounta Home, Session ["FirstName"] è nullo. Gli sviluppatori devono creare BaseControllere definire un campo protetto ( internal protected HttpSessionStateBase SharedSession) che possa esporre la Sessionvariabile condivisa in tutti i controller secondari (questo presuppone che tutti i controller delle app ereditino da BaseController)
Bellash

4
Umm, sicuro che ci sia? C'è una variabile di sessione in Controller (il controller di base fornito da MVC).
aeliusd

7
@Bellash questo è completamente sbagliato. Le sessioni sono disponibili su tutti i controller. Ho appena impostato Session ["test"] in HomeController e poi l'ho letto nel mio AccountController.
niico

0

È possibile memorizzare qualsiasi tipo di dati in una sessione utilizzando:

Session["VariableName"]=value;

Questa variabile durerà circa 20 minuti.


-8

Puoi memorizzare qualsiasi valore nella sessione come Session ["FirstName"] = FirstNameTextBox.Text; ma ti suggerirò di prendere come campo statico nel modello assegnare un valore ad esso e puoi accedere a quel valore di campo ovunque nell'applicazione. Non hai bisogno di una sessione. dovrebbe essere evitata.

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

sul controller - Employee.FullName = "ABC"; Ora puoi accedere a questo nome completo ovunque nell'applicazione.


10
La memorizzazione dei dati su campi statici, in particolare i dati utente come il nome del dipendente, causerà gravi problemi in ambienti multiutente. Quando due diversi utenti accedono al sistema, vedranno lo stesso Employee.EmailAddress poiché il campo statico su Employee è lo stesso per ogni istanza.
Gökçer Gökdal
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.