2010-03-05 7 views
5

Obviamente, el enfoque típico de WebForms no funcionará. ¿Cómo se rastrea un usuario en un mundo MVC?¿Cuál es el patrón aceptado para implementar Session en sitios ASP.NET MVC?

+0

estoy interesado en esto por mí mismo. Personalmente, quiero mantener un rastro de navegación, pero no quiero pasar esto en la cadena de consulta. ¿Qué específicamente desea realizar un seguimiento del usuario? –

+1

¿Cuál es el "enfoque típico de WebForms" que no funcionará? –

Respuesta

22

La sesión funciona exactamente de la misma manera que funcionó en Webforms. Si desea almacenar información simple, use la cookie de autenticación de formularios. Si desea almacenar un contenido de carrito de compras, Session es el lugar indicado. Me escribió una entrada de blog sobre using Session with ASP.NET:

supongamos que queremos almacenar una variable entera en Session.We creará envoltura alrededor de la variable de sesión que hace que parezca más bonita:

Primero definimos interfaz:

public interface ISessionWrapper 
{ 
    int SomeInteger { get; set; } 
} 

entonces hacemos HttpContext aplicación:

public class HttpContextSessionWrapper : ISessionWrapper 
{ 
    private T GetFromSession<T>(string key) 
    { 
     return (T) HttpContext.Current.Session[key]; 
    } 

    private void SetInSession(string key, object value) 
    { 
     HttpContext.Current.Session[key] = value; 
    } 

    public int SomeInteger 
    { 
     get { return GetFromSession<int>("SomeInteger"); } 
     set { SetInSession("SomeInteger", value); } 
    } 
} 

GetFromSession y SetInSession son método de ayuda que hacen tomar y s Obtener datos en Session es más fácil. Algunas propiedades integrales usan estos métodos.

Entonces definimos nuestro controlador de base (aplicable a ASP.NET MVC):

public class BaseController : Controller 
{ 
    public ISessionWrapper SessionWrapper { get; set; } 

    public BaseController() 
    { 
     SessionWrapper = new HttpContextSessionWrapper(); 
    } 
} 

Si desea utilizar el controlador fuera de sesión, que acaba de crear o inyectar nueva HttpContextSessionWrapper().

Puede reemplazar SessionWrapper con el simulacro de ISessionWrapper en las pruebas del Controlador, por lo que ya no depende de HttpContext. La sesión también es más fácil de usar, porque en lugar de llamar a (int) Session ["SomeInteger"], llama a SessionWrapper.SomeInteger. Se ve mejor, ¿no?

Puede tener la tentación de crear una clase estática que cubra el objeto Session y no necesite definir ninguna interfaz o inicialización en BaseController, pero pierde algunas de sus ventajas, especialmente cuando se trata de probar y reemplazar con otra implementación .

+0

¿Por qué escribiría una interfaz y una clase contenedora cuando el marco ya le proporciona 'HttpContext.Current.Session [key]'? –

+8

Porque: 1. var cart = (List ) HttpContext.Current.Session [key] se ve horrible y SessionWrapper.CartItems se ve bien. 2. Es más fácil escribir una prueba para ISessionWrapper. ISessionWrapper puede ser fácilmente modificable y reemplazado por contenido para varios escenarios de prueba. 3. Pierde dependencia. Si quería usar otro almacenamiento en lugar de Session, simplemente creo otra implementación de ISessionWrapper. Tienes que reemplazar el código en cada controlador que usa Session. – LukLed

+0

buenos puntos. Aunque no puedo recuperar el voto a menos que edites la publicación. –

2

Aquí es un código que utilizo, sólo un poco versión "mejorada" de la versión anterior:

private T GetFromSessionStruct<T>(string key, T defaultValue = default(T)) where T : struct 
{ 
    object obj = HttpContext.Current.Session[key]; 
    if (obj == null) 
    { 
     return defaultValue; 
    } 
    return (T)obj; 
} 

private T GetFromSession<T>(string key) where T : class 
{ 
    object obj = HttpContext.Current.Session[key]; 
    return (T)obj; 
} 

private T GetFromSessionOrDefault<T>(string key, T defaultValue = null) where T : class 
{ 
    object obj = HttpContext.Current.Session[key]; 
    if (obj == null) 
    { 
     return defaultValue ?? default(T); 
    } 
    return (T)obj; 
} 

private void SetInSession<T>(string key, T value) 
{ 
    if (value == null) 
    { 
     HttpContext.Current.Session.Remove(key); 
    } 
    else 
    { 
     HttpContext.Current.Session[key] = value; 
    } 
} 
+0

cómo implementaría, ¿puede mostrarnos algunos ejemplos del código anterior? –

Cuestiones relacionadas