¿Qué debo hacer si la sesión ASP.NET actual es nula?

125

En mi aplicación web, hago algo como esto para leer las variables de sesión:

if (HttpContext.Current.Session != null &&  HttpContext.Current.Session["MyVariable"] != null)
{
    string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}

Entiendo por qué es importante verificar por qué HttpContext.Current.Session ["MyVariable"] es nulo (es posible que la variable aún no se haya almacenado en la sesión o que la sesión se haya restablecido por varias razones), pero ¿por qué debo verificarla? si HttpContext.Current.Sessiones nulo?

Entiendo que la sesión es creada automáticamente por ASP.NET, por lo tanto, HttpContext.Current.Session nunca debe ser nulo. ¿Es correcta esta suposición? Si puede ser nulo, ¿significa que también debería verificarlo antes de almacenar algo en él?

if (HttpContext.Current.Session != null)
{
    HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
    // What should be done in this case (if session is null)?
    // Is it possible to force the session to be created if it doesn't exist?
}
Antonio
fuente
ASP.NET WebApi tendrá un comportamiento diferente, puede verificarlo en Acceso a la sesión utilizando la API web de ASP.NET
Tiago Gouvêa

Respuestas:

158

Sí, el objeto Session puede ser nulo, pero solo en ciertas circunstancias, con las que rara vez se encontrará:

Si solo tiene código en las páginas, no se encontrará con esto. La mayor parte de mi código ASP .NET usa Session sin verificar null repetidamente. Sin embargo, es algo en lo que pensar si está desarrollando un IHttpModule o si no está en los detalles más valiosos de ASP .NET.

Editar

En respuesta al comentario: si el estado de la sesión está disponible o no depende de si el evento AcquireRequestState se ha ejecutado para la solicitud. Aquí es donde el módulo de estado de sesión hace su trabajo leyendo la cookie de sesión y encontrando el conjunto apropiado de variables de sesión para usted.

AcquireRequestState se ejecuta antes de entregar el control a su página. Entonces, si está llamando a otra funcionalidad, incluidas las clases estáticas, desde su página, debería estar bien.

Si tiene algunas clases haciendo lógica de inicialización durante el inicio, por ejemplo en el evento Application_Start o mediante el uso de un constructor estático, el estado de la sesión podría no estar disponible. Todo se reduce a si hay una solicitud actual y se ha ejecutado AcquireRequestState.

Además, si el cliente ha deshabilitado las cookies, el objeto Sesión seguirá estando disponible, pero en la próxima solicitud, el usuario volverá con una nueva Sesión vacía. Esto se debe a que el cliente recibe una bolsa de estado de sesión si todavía no la tiene. Si el cliente no transporta la cookie de sesión, no tenemos forma de identificar al cliente como el mismo, por lo que se le dará una nueva sesión una y otra vez.

driis
fuente
66
Solo una actualización rápida que encontré hoy. ¡La sesión no está disponible en el constructor de la página! Solo en el evento Init o después de eso.
Nuno Agapito
Acabo de encontrar un HttpContext.Current.Session == null es un código llamado por un evento Page_Load de una página maestra. Aparentemente, esto puede ocurrir en el contexto de una página. Si inspecciono el objeto HttpContext.Current, la mayoría de los miembros se inicializan, pero CurrentNotification e IsPostNotification arrojan un error: {System.PlatformNotSupportedException}. Cualquiera sea la causa, este problema no se ha producido en la producción, donde se ha ejecutado durante años. La plataforma es Windows Server 2003 R2 SP2, la aplicación tiene el marco objetivo .Net 3.5 y se ejecuta en IIS con el estado de sesión habilitado.
R. Schreurs
También descubrí que, cuando IIS atiende una solicitud directa de un archivo de recursos que existe en el disco, como una hoja de estilo, HttpContext.Current.Sessionpuede ser nulo para codificar en `Application_AcquireRequestState '. Sin embargo, la solicitud de la página en sí hace que el objeto de sesión esté disponible para codificar allí. Esto está bajo MVC.NET 4 al menos.
ingrediente_15939
Creo que también podría ser nulo si está dentro de una acción MVC en caché de salida.
user2173353
40

La siguiente declaración no es del todo precisa:

"Entonces, si está llamando a otra funcionalidad, incluidas las clases estáticas, desde su página, debería estar bien"

Estoy llamando a un método estático que hace referencia a la sesión a través de HttpContext.Current.Session y es nulo. Sin embargo, estoy llamando al método a través de un método de servicio web a través de ajax usando jQuery.

Como descubrí aquí , puede solucionar el problema con un atributo simple en el método o usar el objeto de sesión de servicio web:

Sin embargo, hay un truco, para acceder al estado de la sesión dentro de un método web, debe habilitar la administración del estado de la sesión de la siguiente manera:

[Método web (EnableSession = true)]

Al especificar el valor EnableSession, ahora tendrá una sesión administrada para jugar. Si no especifica este valor, obtendrá un objeto de sesión nulo, y lo más probable es que encuentre excepciones de referencia nula al intentar acceder al objeto de sesión.

Gracias a Matthew Cozier por la solución.

Solo pensé en agregar mis dos centavos.

Ed

Ed Bishop
fuente
1
gracias Ed, la sesión aparecía como nula en el método web; agregar esto lo solucionó. +1
fusi
1
Bueno, cuando está llamando a un servicio web, utiliza otra solicitud que no sea para la página, por lo que esa declaración sigue siendo correcta, IMO.
driis
MSDN Docs aquí - the default value is false. Funciona de maravilla.
Benjineer
22

Si su instancia de sesión es nula y está en un archivo 'ashx', simplemente implemente la interfaz 'IRequiresSessionState'.

Esta interfaz no tiene ningún miembro, por lo que solo necesita agregar el nombre de la interfaz después de la declaración de clase (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState
mathijsuitmegen
fuente
Muchas gracias, la sesión fue nula en mi clase de inicio de sesión. Cuando agregué este código a mi controlador ashx, también se convirtió en sesión en mi clase
Ateş Danış
Creo que esto responde la pregunta bastante bien. Muchas gracias.
Sachin Joseph
2

Artículos técnicos de ASP.NET

RESUMEN: En ASP.NET, cada página web deriva de la clase System.Web.UI.Page. La clase Page agrega una instancia del objeto HttpSession para datos de sesión. La clase de página expone diferentes eventos y métodos para la personalización. En particular, el método OnInit se usa para establecer el estado de inicialización del objeto Page. Si la solicitud no tiene la cookie de sesión, se emitirá una nueva cookie de sesión para el solicitante.

EDITAR:

Sesión: un concepto para principiantes

RESUMEN: La sesión se crea cuando el usuario envía una primera solicitud al servidor para cualquier página de la aplicación web, la aplicación crea la sesión y envía la identificación de la sesión al usuario con la respuesta y se almacena en la máquina del cliente como una pequeña cookie . Entonces, idealmente, la "máquina que ha desactivado las cookies, la información de la sesión no se almacenará".

Adatapost
fuente
2

En mi caso ASP.NET State Servicefue detenido. Cambio de la Startup typeque Automatice iniciar el servicio manualmente por primera vez resuelto el problema.

Eric
fuente