web-dev-qa-db-fra.com

Ce qui provoque "L'état de session a créé un identifiant de session, mais ne peut pas l'enregistrer car la réponse a déjà été vidée par l'application."

Je reçois cette faute par intermittence. 

J'ai trouvé ce lien qui résume assez bien ce que j'ai pu trouver sur Google: http://www.wacdesigns.com/2009/02/03/session-state-has-created-a-session -id-but-can-save-it-parce que la réponse a déjà été vidé par l'application/

En gros, cela signifie que vous pouvez essayer de définir le paramètre de configuration Web, DisplayWhenNewSession, ou essayer de réactiver l’état de la session en obtenant le Session.SessionID dans Session_OnStart.

Mais est-ce que quelqu'un:

a) avoir une explication à cela

ou même mieux, b) avoir un correctif éprouvé

Je me rends compte que je ne peux pas vider la réponse après avoir fait quoi que ce soit qui aurait une incidence sur l'en-tête de la réponse http. Si je le faisais, cela provoquerait une erreur à chaque fois mais ceci est intermittent. Le SessionID devrait sûrement être créé automatiquement par ASP.NET au début de la réponse de la page, avant tout élément de la page ASPX ou du Page_Load (qui est l'endroit où tous mes flush sont appelés).

Mise à jour: Après réflexion, je réalise que cela se produit lors de la transmission en continu d'un fichier au navigateur. La plupart des navigateurs sont en fait des moteurs de recherche. Je peux recréer cette erreur en démarrant un téléchargement, puis en fermant le navigateur. Par conséquent, les navigateurs n'attendent probablement pas la fin du téléchargement avant d'annuler l'opération de téléchargement. J'ai également vu cela sur d'autres pages normales, mais 99% du temps, ce sont des pages de téléchargement.

68
mike nelson

J'ai!

Dans le fichier global.asax, procédez comme suit:

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

Si facile. Ça marche!

74
eitama

Cette erreur semble apparaître lorsque:

  • Le démarrage de l'application

  • Vous utilisez un fichier Global.asax même si vous faites ou non quelque chose dans les événements Session_Start/End

  • Votre application force le Flush de la réponse trop tôt

  • Vous n'utilisez pas la session avant la couleur

Il est déclenché par l'état de la session lorsqu'il tente de sauvegarder l'ID de session lors de la publication:

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)

Je pense que la présence de Global.asax entraîne la sauvegarde de l'ID de session lors de sa publication par le SessionStateModule (tard?) Même si aucune session n'a été utilisée à la place de HttpSessionState lors de l'appel de SessionID.

C'est la raison pour laquelle string sessionId = Session.SessionID; astuce éviter le problème.

Je suppose que cela n'apparaît qu'au démarrage de l'application en raison des comportements d'initialisation.

Solutions/astuces :

  • Évitez de rincer dans Page_Load

  • Désactiver l'état de session sur la page (EnableSessionState)

  • Utilisez l'astuce SessionID avant la couleur

  • Utilisez Response.End () à la place de .Flush () si vous ne vous souciez pas des erreurs pouvant survenir après votre vidage.

19
JoeBilly

Je pense que le problème ici est peut-être précisément que vous faites quelque chose qui cause la sortie de la page pendant Page_Load, qui, selon le Vue d'ensemble du cycle de vie d'une page ASP.NET , est bien avant l'étape de rendu.

Veillez à ne rien faire qui puisse déclencher la sortie de la page avant l'étape PreRender.

6
Curt J. Sampson

Ayant moi-même rencontré ce problème, je pensais partager mes découvertes.

Le paramètre web.config, DisplayWhenNewSession, n'est pas pertinent car il ne s'applique qu'à un contrôle personnalisé particulier sur Codeplex (désolé j'ai perdu le lien).

L’autre suggestion semble fonctionner en initialisant tôt SessionId. J'ai creusé dans le code en utilisant Reflector et je ne pouvais pas vraiment comprendre en quoi cela empêchait l'erreur ici, mais cela a certainement fonctionné pour nous!

Comme la plupart des personnes qui semblent rencontrer ce bogue, nous n'appelons pas explicitement Response.Flush () dans l'application. Nous utilisons également MVC, pour mémoire.

3
Gaz

Je reconnais que c'est très vieux, mais j'ai trouvé une autre raison de l'erreur qui pourrait s'appliquer à d'autres. Si vous utilisez MVC (j’utilisais MVC 4 avec .Net 4.0) et que vous définissiez les pages sur non bufferby en utilisant l’élément web.config 

<pages buffer="false">    

Ensuite, si dans votre code, vous essayez d'insérer des données dans l'objet de session, vous risquez de recevoir cette erreur si le rendu de la page avait commencé avant que votre vue ou action enfant effectue l'accès à l'état de la session.

Dans de tels cas, vous pouvez corriger l'erreur en modifiant le paramètre de tampon ci-dessus sur true. Sinon, déplacez votre code d'accès de session vers la vue principale et non dans une action/vue enfant.

0
Mike Teye