Variables de sesión en ASP.NET MVC

Estoy escribiendo una aplicación web que permitirá a un usuario navegar a varias páginas web dentro del sitio web haciendo ciertas solicitudes. Toda la información que ingresa el usuario se almacenará en un objeto que creé. El problema es que necesito acceder a este objeto desde cualquier parte del sitio web y realmente no sé cuál es la mejor manera de lograrlo. Sé que una solución es usar variables de sesión, pero no sé cómo usarlas en asp .net MVC. ¿Y dónde declararía una variable de sesión? ¿Hay alguna otra manera?

    Creo que querrás pensar si las cosas realmente pertenecen a un estado de sesión. Esto es algo que me encuentro haciendo de vez en cuando y es un buen enfoque fuertemente tipado para todo el asunto, pero debe tener cuidado al poner las cosas en el contexto de la sesión. No todo debería estar allí solo porque pertenece a algún usuario.

    en global.asax enganche el evento OnSessionStart

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

    Desde cualquier lugar del código donde la propiedad HttpContext.Current! = Null puede recuperar ese objeto. Lo hago con un método de extensión.

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

    De esta forma puedes codificar

     void OnLoad(...) { var sessionObj = HttpContext.Current.GetMySessionObject(); // do something with 'sessionObj' } 

    La respuesta aquí es correcta, sin embargo tuve problemas para implementarla en una aplicación ASP.NET MVC 3. Quería acceder a un objeto Session en un controlador y no podía entender por qué seguía obteniendo una “Instancia no configurada como instancia de un error Object”. Lo que noté es que en un controlador cuando intenté acceder a la sesión haciendo lo siguiente, seguí recibiendo ese error. Esto se debe al hecho de que this.HttpContext es parte del objeto Controller.

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

    Sin embargo, lo que quería era HttpContext, que es parte del espacio de nombres System.Web porque este es el que la respuesta anterior sugiere usar en Global.asax.cs. Así que tuve que hacer explícitamente lo siguiente:

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

    esto me ayudó, no estoy seguro si hice algo que no sea MO por aquí, ¡pero espero que ayude a alguien!

    Como no me gusta ver “HTTPContext.Current.Session” sobre el lugar, utilizo un patrón de singleton para acceder a las variables de la sesión, que le da un acceso fácil a la bolsa de datos fuertemente tipada.

     [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; } // ... 

    entonces puedes acceder a tus datos desde cualquier lugar:

     SessionSingleton.Current.SessionVariable = "Hello, World!"; 

    Si está utilizando asp.net mvc, aquí hay una forma simple de acceder a la sesión.

    Desde un controlador:

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

    Desde una vista:

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

    Esta definitivamente no es la mejor manera de acceder a las variables de sesión, pero es una ruta directa. Por lo tanto, úselo con precaución (preferiblemente durante el prototipado rápido) y use un Wrapper / Container y OnSessionStart cuando sea apropiado.

    HTH

    Bueno, en mi humilde opinión …

    1. nunca haga referencia a una sesión dentro de su página de vista / maestra
    2. minimiza el uso de Session. MVC proporciona TempData obj para esto, que es básicamente una sesión que vive para un solo viaje al servidor.

    Con respecto al n. ° 1, tengo una vista maestra fuertemente tipada que tiene una propiedad para acceder a todo lo que representa el objeto de sesión … en mi caso, la vista maestra de estilo rígido es genérica, lo que me da cierta flexibilidad con respecto a páginas de vista fuertemente tipadas

     ViewMasterPage AdminViewModel { SomeImportantObjectThatWasInSession ImportantObject } AdminViewModel : AdminViewModel where TModel : class { TModel Content } 

    y entonces…

     ViewPage> 

    Aunque no sé sobre asp.net mvc, pero esto es lo que deberíamos hacer en un sitio web .net normal. Debería funcionar para asp.net mvc también.

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

    Pondrá esto dentro de un método para facilitar el acceso. HTH

    Hay 3 formas de hacerlo.

    1. Puede acceder directamente a HttpContext.Current.Session

    2. Puede simular HttpContextBase

    3. Crear un método de extensión para HttpContextBase

    Prefiero la tercera vía. Este enlace es una buena referencia.

    Obtener / Establecer métodos de sesión HttpContext en BaseController vs Mocking HttpContextBase para crear métodos Get / Set

    Grandes respuestas de los muchachos, pero les advierto que no confíen siempre en la sesión. Es rápido y fácil de hacer, y por supuesto funcionaría, pero no sería genial en todas las carreras.

    Por ejemplo, si se encuentra con un escenario en el que su hosting no permite el uso de la sesión, o si se encuentra en una granja de servidores web, o en el ejemplo de una aplicación compartida de SharePoint.

    Si desea una solución diferente, puede utilizar un Contenedor IOC como Castle Windsor , crear una clase de proveedor como un contenedor y luego mantener una instancia de su clase utilizando el estilo de vida de solicitud o sesión, dependiendo de sus requisitos.

    El COI garantizará que se devuelva la misma instancia cada vez.

    Más complicado sí, si necesita una solución simple solo use la sesión.

    Aquí hay algunos ejemplos de implementación que están fuera de interés.

    Usando este método, puedes crear una clase de proveedor a lo largo de las líneas de:

     public class CustomClassProvider : ICustomClassProvider { public CustomClassProvider(CustomClass customClass) { CustomClass = customClass; } public string CustomClass { get; private set; } } 

    Y registre algo así como:

     public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component.For().UsingFactoryMethod( () => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest()); } 

    Puede usar ViewModelBase como clase base para todos los modelos, esta clase se encargará de extraer datos de la sesión

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

    Puede escribir un método de extensión en HttpContextBase para tratar los datos de la sesión

     T FromSession(this HttpContextBase context ,string key,Action 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; } 

    Use esto como a continuación en el controlador

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

    El segundo argumento es opcional, se usará para completar los datos de la sesión para esa clave cuando el valor no está presente en la sesión.

    Mi forma de acceder a las sesiones es escribir una clase de ayuda que encapsula los diversos nombres de campo y sus tipos. Espero que este ejemplo ayude:

     using System; using System.Collections.Generic; using System.Web; using System.Web.SessionState; namespace dmkp { ///  /// Encapsulates the session state ///  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; } } } }