2009-04-09 8 views

risposta

33

Utilizzerei l'iniezione di dipendenza e passerò l'istanza di HttpContext (o solo la sessione) alla classe che deve accedere alla Sessione. L'altra alternativa è fare riferimento a HttpContext.Current, ma ciò renderà più difficile da testare poiché si tratta di un oggetto statico.

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"]; 
      ... 
     } 
    } 
+1

Grazie per la risposta. Sembra che ci siano alcuni framework di Iniezione delle dipendenze. Quale framework DI suggerisci? È necessario leggere articoli su DI? :) – xraminx

+1

questo sembra eccessivamente complicato per ciò che il poster originale stava chiedendo. –

+1

@xraminx: non confondere ciò che sto suggerendo con un framework DI. Sto parlando di usare DI, il modello, non un quadro. L'idea è di passare un'istanza della dipendenza alla classe piuttosto che crearne una o utilizzare un'istanza statica. Molto più facile da testare l'unità tramite derisione. – tvanfosson

0

non l'ho fatto io stesso, ma questo campione dal blog di Chad Meyer potrebbe aiutare (da questo post: http://www.chadmyers.com/Blog/archive/2007/11/30/asp.net-webforms-and-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); 
} 
20

Hai solo bisogno di chiamare attraverso la HttpContext in questo modo:

HttpContext.Current.Session["MyValue"] = "Something"; 
+1

@Nick: prova l'unità testando il HttpContext statico e vedi com'è facile. L'ho fatto - no grazie. – tvanfosson

+2

FYI: c'è un motivo per cui i progettisti di framework hanno introdotto HttpSessionStateBase e HttpContextBase nelle versioni più recenti del framework e perché è possibile modificare HttpContext in un controller modificando il contesto del controller. Rende molto più facile testare le tue azioni. – tvanfosson

+14

Il poster originale non ha mai chiesto informazioni sui test. Ha chiesto come avrebbe potuto accedere alla sessione. –

0

Vorrei anche racchiudere tutte le variabili di sessione in un singolo file di classe. In questo modo puoi usare intelliSense per selezionarli. Questo riduce il numero di passi nel codice in cui è necessario specificare le "stringhe" per la sessione.

1

Ecco la mia versione di una soluzione per questo problema. Si noti che io uso anche un iniezione di dipendenza, così, l'unica differenza è che l'oggetto "sessione" si accede ha gettato un Singleton

private iSession _Session; 

private iSession InternalSession 
{ 
    get 
    { 

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

Ecco la classe SessionDecorator, che utilizza un modello Decorator per avvolgere la sessione intorno un'interfaccia:

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

Spero che questo aiuti :)