web-dev-qa-db-fra.com

ASP.NET MVC - Comment accéder aux données de session dans des endroits autres que le contrôleur et les vues

Nous pouvons accéder aux données de session dans des contrôleurs et des vues comme celle-ci:

Session["SessionKey1"]

Comment accédez-vous aux valeurs de session à partir d'une classe autre qu'un contrôleur ou une vue?

23
xraminx

J'utiliserais l'injection de dépendance et transmettrais l'instance de HttpContext (ou simplement la session) à la classe qui a besoin d'accéder à la session. L'autre alternative consiste à référencer HttpContext.Current, mais cela rendra le test plus difficile car il s'agit d'un objet statique.

   public ActionResult MyAction()
   {

       var foo = new Foo( this.HttpContext );
       ...
   }


   public class Foo
   {
        private HttpContextBase Context { get; set; }

        public Foo( HttpContextBase context )
        {
            this.Context = context;
        }

        public void Bar()
        {
            var value = this.Context.Session["barKey"];
            ...
        }
   }
34
tvanfosson

Vous avez juste besoin de l'appeler via HttpContext comme ceci:

HttpContext.Current.Session["MyValue"] = "Something";
24
Nick Berardi

Voici ma version d'une solution à ce problème. Notez que j'utilise également une injection de dépendance, la seule différence majeure est que l'objet "session" est accessible via un Singleton

private iSession _Session;

private iSession InternalSession
{
    get
    {

        if (_Session == null)
        {                
           _Session = new SessionDecorator(this.Session);
        }
        return _Session;
    }
}

Voici la classe SessionDecorator, qui utilise un modèle Decorator pour envelopper la session autour d'une interface:

public class SessionDecorator : iSession
{
    private HttpSessionStateBase _Session;
    private const string SESSIONKEY1= "SESSIONKEY1";
    private const string SESSIONKEY2= "SESSIONKEY2";

    public SessionDecorator(HttpSessionStateBase session)
    {
        _Session = session;
    }

    int iSession.AValue
    {
           get
        {
            return _Session[SESSIONKEY1] == null ? 1 : Convert.ToInt32(_Session[SESSIONKEY1]);
        }
        set
        {
            _Session[SESSIONKEY1] = value;
        }
    }

    int iSession.AnotherValue
    {
        get
        {
            return _Session[SESSIONKEY2] == null ? 0 : Convert.ToInt32(_Session[SESSIONKEY2]);
        }
        set
        {
            _Session[SESSIONKEY2] = value;
        }
    }
}`

J'espère que cela t'aides :)

1
Smoothcity

Je voudrais également envelopper toutes les variables de session dans un fichier de classe unique. De cette façon, vous pouvez utiliser intelliSense pour les sélectionner. Cela réduit le nombre de pas dans le code où vous devez spécifier les "chaînes" pour la session.

0
Tony Borf

Je ne l'ai pas fait moi-même, mais cet échantillon du blog de Chad Meyer pourrait aider (à partir de ce message: http://www.chadmyers.com/Blog/archive/2007/11/30/asp.net-webforms -et-mvc-in-the-same-project.aspx )

[ControllerAction]
public void Edit(int id)
{
    IHttpSessionState session = HttpContext.Session;

    if (session["LoggedIn"] == null || ((bool)session["LoggedIn"] != true))
        RenderView("NotLoggedIn");

    Product p = SomeFancyDataAccess.GetProductByID(id);

    RenderView("Edit", p);
}
0
Chuck