¿Qué está causando que el estado de la sesión haya creado un ID de sesión, pero no puede guardarlo porque la aplicación ya eliminó la respuesta?

80

Recibo esta falla de forma intermitente.

Encontré este enlace que resume bastante bien lo que pude encontrar en Google: http://www.wacdesigns.com/2009/02/03/session-state-has-created-a-session-id-but- no puedo-guardar-porque-la-respuesta-ya-fue-eliminada-por-la-aplicación /

Básicamente, dice que puede intentar configurar la configuración web DisplayWhenNewSession, o intentar darle vida al estado de la sesión obteniendo Session.SessionID en Session_OnStart.

Pero, ¿alguien:

a) tener una explicación para esto

o incluso mejor, b) tener una solución probada

Me doy cuenta de que no puedo vaciar la respuesta después de hacer algo que afecte el encabezado de respuesta http. Si hiciera esto, causaría un error cada vez, pero esto es intermitente. El SessionID seguramente debería ser creado por ASP.NET al comienzo de la respuesta de la página automáticamente, antes de cualquier cosa en la página ASPX o Page_Load (que es donde se llaman todos mis flushes).

Actualización: Reflexionando, me doy cuenta de que esto está sucediendo cuando se transmite un archivo al navegador. La mayoría de los navegadores son robots de motores de búsqueda. Puedo recrear este error iniciando una descarga y luego cerrando el navegador, por lo que presumiblemente los navegadores no están esperando a que se complete la descarga antes de cancelar la operación de descarga. También he visto esto en otras páginas normales, pero el 99% del tiempo son páginas de descarga.

mike nelson
fuente
1
Tengo exactamente el mismo problema. La única razón por la que lo vi fue cuando puse el manejo de excepciones en Global.asax. Es muy intermitente. ¡Sería genial si alguien supiera la respuesta a esto!
Scott Ferguson
6
El enlace ahora está roto :-(
Casebash

Respuestas:

85

¡Yo tengo!

En el archivo global.asax haces esto:

void Session_Start(object sender, EventArgs e) 
{
    // Code that runs when a new session is started
    string sessionId = Session.SessionID;
}

Tan fácil. ¡Funciona!

eitama
fuente
¿Es este un método público / protegido? En su forma privada, supongo que debería estar protegido. ¿Está completa la muestra, el hecho de que el sessionId no se haya guardado, supongo que está bien? Lo importante es la activación de la creación, ¿verdad?
Chris Kimpton
Gracias. Creo que esto generalmente funciona, así que lo marcaré como respuesta aceptada, aunque no estoy 100% seguro. ¿Alguien puede comentar, por favor, si encuentra un caso en el que esto no funciona? Gracias.
Mike Nelson
Simplemente agregué este método a mi archivo global.asax y eliminó mi mensaje de error, que era el mismo que la pregunta, ¡muchas gracias eitama!
vanhornRF
Esto resolvió mi problema (estaba forzando la descarga) ¿Pero sabes por qué esto funciona como una solución?
Amistoso
Esta respuesta me acaba de ahorrar muchas horas. Nunca lo hubiera adivinado. ¡Gracias!
HockeyJ
23

Este error parece aparecer cuando:

  • El inicio de la aplicación

  • Estás usando un Global.asax incluso si estás haciendo algo en los eventos Session_Start / End o no

  • Su aplicación fuerza el Flush de la respuesta demasiado pronto

  • No estás usando la sesión antes de la descarga

Lo genera el estado de la sesión cuando intenta guardar el ID de sesión en el lanzamiento:

System.Web.SessionState.SessionIDManager.SaveSessionID(HttpContext context, String id, Boolean& redirected, Boolean& cookieAdded)
System.Web.SessionState.SessionStateModule.CreateSessionId()
System.Web.SessionState.SessionStateModule.DelayedGetSessionId()
System.Web.SessionState.SessionStateModule.ReleaseStateGetSessionID()
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs)
System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Creo que la presencia de Global.asax hace que el SessionStateModule guarde el ID de sesión en el lanzamiento (¿tarde?) Incluso si no se ha utilizado ninguna sesión en lugar de HttpSessionState cuando se llama a SessionID.

Es la razón por la que string sessionId = Session.SessionID; truco evita el problema.

Supongo que solo aparece al iniciar la aplicación debido a los comportamientos de inicialización.

Soluciones / trucos :

  • Evite vaciar en Page_Load como ya se dijo

  • Desactivar el estado de la sesión en la página (EnableSessionState)

  • Usa el truco de SessionID antes del vaciado

  • Use Response.End () en lugar de .Flush () si no le importan los errores que pueden ocurrir después de su descarga

JoeBilly
fuente
6

Creo que el problema aquí puede ser exactamente que está haciendo algo para provocar la salida de la página durante Page_Load, lo cual, de acuerdo con ASP.NET Page Lifecycle Overview, es mucho antes de la etapa de renderizado.

Asegúrese de no hacer nada que pueda activar la salida de página hasta después de la PreRenderetapa.

cjs
fuente
Gracias, echaré un vistazo a eso esta noche. ¿No estás seguro de por qué sería intermitente?
mike nelson
una respuesta condicional. ¿Escribir () en un evento inapropiado tal vez?
Josh E
3

Habiéndome encontrado con este problema, pensé en compartir mis hallazgos.

La configuración de web.config DisplayWhenNewSession es irrelevante ya que solo se aplica a un control personalizado en particular en Codeplex (lo siento, he perdido el enlace).

La otra sugerencia parece funcionar inicializando el SessionId antes. Busqué en el código usando Reflector y no pude ver cómo esto previno el error aquí, ¡pero ciertamente funcionó para nosotros!

Como la mayoría de las personas que parecen encontrarse con este error, no estamos llamando explícitamente a Response.Flush () en ninguna parte de la aplicación. También estamos usando MVC, para que conste.

Gaz
fuente
0

Reconozco que esto es muy antiguo, pero encontré otra razón para el error que podría aplicarse a otros. Si está usando MVC (estaba usando MVC 4 con .Net 4.0) y configura las páginas para que no se almacenen en búfer mediante el elemento web.config

<pages buffer="false">    

Luego, si en su código intenta insertar datos en el objeto de sesión, puede correr el riesgo de recibir este error si la página comenzó a renderizarse antes que su vista secundaria o acción que realiza el acceso de estado de sesión.

En tales casos, puede corregir el error cambiando la configuración del búfer anterior a verdadera. Alternativamente, mueva su código de acceso a la sesión a la vista principal y no a una acción secundaria / vista secundaria.

Mike Teye
fuente