Zmienne sesji w ASP.NET MVC

Piszę aplikację internetową, która pozwoli użytkownikowi na przeglądanie wielu stron internetowych w witrynie, składając określone żądania. Wszystkie informacje wprowadzone przez Użytkownika będą przechowywane w utworzonym przeze mnie obiekcie. Problem polega na tym, że potrzebuję dostępu do tego obiektu z dowolnej części strony internetowej i naprawdę Nie wiem, jak najlepiej to osiągnąć. Wiem, że jednym z rozwiązań jest użycie zmiennych sesji, ale nie wiem, jak ich używać w asp.net MVC. A gdzie ja zadeklarować zmienną sesji? Jest jakiś inny sposób?

Author: N30, 2009-02-18

10 answers

Myślę, że będziesz chciał pomyśleć o tym, czy rzeczy naprawdę należą do stanu sesji. To jest coś, co robię od czasu do czasu i jest to ładne mocno wpisane podejście do całości, ale powinieneś być ostrożny, umieszczając rzeczy w kontekście sesji. Nie wszystko powinno tam być tylko dlatego, że należy do jakiegoś użytkownika.

In global.asax hook The onsessionstart event

void OnSessionStart(...)
{
    HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject());
}

Z dowolnego miejsca w kodzie, w którym znajduje się HttpContext.Aktualna nieruchomość != null można Odzyskaj ten obiekt. Robię to metodą przedłużania.

public static MySessionObject GetMySessionObject(this HttpContext current)
{
    return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null;
}

W ten sposób możesz w kodzie

void OnLoad(...)
{
    var sessionObj = HttpContext.Current.GetMySessionObject();
    // do something with 'sessionObj'
}
 125
Author: John Leidegren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-16 19:59:34

Odpowiedź tutaj jest prawidłowa, jednak starałem się wdrożyć ją w ASP.NET aplikacja MVC 3. Chciałem uzyskać dostęp do obiektu sesji w kontrolerze i nie mogłem zrozumieć, dlaczego ciągle otrzymywałem "instancję nie ustawioną na instancję błędu obiektu". Zauważyłem, że w kontrolerze, gdy próbowałem uzyskać dostęp do sesji, wykonując następujące czynności, wciąż otrzymywałem ten błąd. Wynika to z faktu, że to.HttpContext jest częścią obiektu Controller.

this.Session["blah"]
// or
this.HttpContext.Session["blah"]

Jednak to, co ja poszukiwany był HttpContext, który jest częścią systemu.Web namespace, ponieważ jest to ta, którą powyższa odpowiedź sugeruje użycie w Global.asax.cs. Więc musiałem wyraźnie zrobić, co następuje:

System.Web.HttpContext.Current.Session["blah"]

To mi pomogło, Nie wiem, czy zrobiłem coś, co nie jest sposobem działania tutaj, ale mam nadzieję, że to komuś pomoże!

 49
Author: Tomasz Iniewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-24 18:31:18

Ponieważ nie lubię widzieć " HTTPContext.Aktualne.Session " o miejscu, używam wzoru Singletona, aby uzyskać dostęp do zmiennych sesji, daje łatwy dostęp do silnie wpisanego worka danych.

[Serializable]
public sealed class SessionSingleton
{
    #region Singleton

    private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207";

    private SessionSingleton()
    {

    }

    public static SessionSingleton Current
    {
        get
        {
            if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null )
            {
                HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton();
            }

            return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton;
        }
    }

    #endregion

    public string SessionVariable { get; set; }
    public string SessionVariable2 { get; set; }

    // ...

Wtedy możesz uzyskać dostęp do swoich danych z dowolnego miejsca:

SessionSingleton.Current.SessionVariable = "Hello, World!";
 21
Author: Dead.Rabit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-10 12:41:38

Jeśli używasz asp.net mvc, Oto prosty sposób na dostęp do sesji.

Od kontrolera:

{Controller}.ControllerContext.HttpContext.Session["{name}"]

Z widoku:

<%=Session["{name}"] %>

To zdecydowanie nie jest najlepszy sposób na dostęp do zmiennych sesji, ale jest to bezpośrednia trasa. Używaj go więc ostrożnie (najlepiej podczas szybkiego prototypowania) i używaj Owijarki/kontenera i zacznij Onsession, gdy stanie się to właściwe.

HTH

 14
Author: robertz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-24 13:36:52

IMHO..

  1. nigdy nie odwoływaj się do sesji wewnątrz widoku / strony wzorcowej
  2. zminimalizuj wykorzystanie sesji. MVC zapewnia TempData obj dla tego, co jest w zasadzie sesją, która żyje na pojedynczą podróż do serwera.

W odniesieniu do #1, mam silnie wpisany widok główny, który ma właściwość dostępu do dowolnego obiektu sesji represents....in mój przykład stongly typed Master View jest ogólny, co daje mi pewną elastyczność w odniesieniu do silnie wpisywane strony widoku

ViewMasterPage<AdminViewModel>

AdminViewModel
{
    SomeImportantObjectThatWasInSession ImportantObject
}

AdminViewModel<TModel> : AdminViewModel where TModel : class
{
   TModel Content
}

I wtedy...

ViewPage<AdminViewModel<U>>
 13
Author: E Rolnicki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-18 07:32:32

Chociaż Nie wiem o asp.net mvc, ale to właśnie powinniśmy zrobić w normalnej witrynie. NET. Powinno działać na asp.net mvc również.

YourSessionClass obj=Session["key"] as YourSessionClass;
if(obj==null){
obj=new YourSessionClass();
Session["key"]=obj;
}

Umieściłbyś to w metodzie łatwego dostępu. HTH

 7
Author: DotNET,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-18 07:11:54

Są na to 3 sposoby.

  1. Możesz uzyskać bezpośredni dostęp HttpContext.Current.Session

  2. Możesz kpić HttpContextBase

  3. Utwórz metodę rozszerzenia dla HttpContextBase

Wolę trzecią drogę.Ten link jest dobrym punktem odniesienia.

Get/Set HttpContext Session Methods in BaseController vs Mocking HttpContextBase to create Get / Set methods

 7
Author: Mangesh Pimpalkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:56

Moim sposobem dostępu do sesji jest napisanie klasy pomocniczej, która zawiera nazwy różnych pól i ich typy. Mam nadzieję, że ten przykład pomoże:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;

namespace dmkp
{
    /// <summary>
    /// Encapsulates the session state
    /// </summary>
    public sealed class LoginInfo
    {
        private HttpSessionState _session;
        public LoginInfo(HttpSessionState session)
        {
            this._session = session;
        }

        public string Username
        {
            get { return (this._session["Username"] ?? string.Empty).ToString(); }
            set { this._session["Username"] = value; }
        }

        public string FullName
        {
            get { return (this._session["FullName"] ?? string.Empty).ToString(); }
            set { this._session["FullName"] = value; }
        }
        public int ID
        {
            get { return Convert.ToInt32((this._session["UID"] ?? -1)); }
            set { this._session["UID"] = value; }
        }

        public UserAccess AccessLevel
        {
            get { return (UserAccess)(this._session["AccessLevel"]); }
            set { this._session["AccessLevel"] = value; }
        }

    }
}
 7
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-18 09:13:54

Świetne odpowiedzi od chłopaków, ale ostrzegam cię przed zawsze poleganiem na sesji. Jest to szybkie i łatwe do zrobienia, i oczywiście będzie działać, ale nie będzie wielki w każdym circrumstances.

Na przykład, jeśli napotkasz scenariusz, w którym hosting nie pozwala na użycie sesji, lub jeśli jesteś na farmie internetowej, lub w przykładzie udostępnionej aplikacji SharePoint.

Jeśli potrzebujesz innego rozwiązania, możesz spojrzeć na to używając kontenera IOC , takiego jak Castle Windsor , tworząc klasę provider jako wrapper, a następnie zachowując jedną instancję klasy używając stylu per request lub session w zależności od wymagań.

IOC zapewni, że za każdym razem zwracana jest ta sama instancja.

Bardziej skomplikowane tak, jeśli potrzebujesz prostego rozwiązania, skorzystaj z sesji.

Oto kilka przykładów implementacji poniżej z zainteresowania.

Używając tej metody można utworzyć klasę provider wzdłuż linii of:

public class CustomClassProvider : ICustomClassProvider
{
    public CustomClassProvider(CustomClass customClass)
    { 
        CustomClass = customClass;
    }

    public string CustomClass { get; private set; }
}

I zarejestrować to coś w stylu:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
            Component.For<ICustomClassProvider>().UsingFactoryMethod(
                () => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest());
    }
 6
Author: shenku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-23 23:38:41

Możesz użyć viewmodelbase jako klasy bazowej dla wszystkich modeli, ta klasa zajmie się pobieraniem danych z sesji

class ViewModelBase 
{
  public User CurrentUser 
  {
     get { return System.Web.HttpContext.Current.Session["user"] as User };
     set 
     {
        System.Web.HttpContext.Current.Session["user"]=value; 
     }
  }
}

Możesz napisać metodę rozszerzenia na HttpContextBase, aby poradzić sobie z danymi sesji

T FromSession<T>(this HttpContextBase context ,string key,Action<T> getFromSource=null) 
{
    if(context.Session[key]!=null) 
    {
        return (T) context.Session[key];
    }
  else if(getFromSource!=null) 
  {
    var value = getFromSource();
   context.Session[key]=value; 
   return value; 
   }
  else 
  return null;
}

Użyj tego jak poniżej w kontrolerze

User userData = HttpContext.FromSession<User>("userdata",()=> { return user object from service/db  }); 

Drugi argument jest opcjonalny zostanie użyty do wypełnienia danych sesji dla tego klucza, gdy wartość nie jest obecna w sesji.

 4
Author: Ajay Kelkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-06 07:06:58