“HttpContext.Actuel.Session” vs Mondiale.asax“.Session”
Récemment, tout en travaillant sur un code pour un ASP.NET projet au travail. Nous avions besoin d'un suivi util pour prendre la base des indicateurs sur l'activité de l'utilisateur (page nombre d'accès etc) nous suivre dans Session
, puis enregistrer les données dans la base de données via Session_End
dans Global.asax
.
J'ai commencé à bidouiller, le code a bien fonctionné, la mise à jour de la DB sur chaque chargement de la page. J'ai voulu supprimer cette DB frapper sur chaque demande si et seulement s'appuyer sur Session_End
pour stocker toutes les données.
Tout le code de suivi est encapsulé dans le Tracker
classe, y compris les propriétés qui sont essentiellement envelopper les variables de Session.
Le problème est que lorsque j'ai exécuté Tracker.Log()
dans le Session_End
méthode, la HttpContext.Actuel.Session
dans le Tracker code n'était pas avec une NullReferenceException
. Maintenant, cela fait sens car HttpContext
se rapporte toujours à la actuel demande, et bien sûr dans Session_End
, il n'y a pas de demande.
Je sais que Global.asax
a un Session
propriété qui retourne un HttpSessionState
qui en fait semble fonctionner correctement (j'ai fini par l'injecter dans le tracker)..
Mais je suis curieux, comment diable puis-je obtenir la même référence à la HttpSessionState
objet utilisé par Global.asax
de à l'extérieur de Global.asax
?
Merci d'avance les gars, j'apprécie l'entrée. 🙂
Peut quelqu'un de bien vouloir mettre un extrait de code pour cette question, la réponse pour les débutants à comprendre. Comment accéder à "Proc" de mode, les valeurs stockées dans le courant.session somnwhere dans l'application, puis d'y accéder en mondial.asax fichier. Puis-je simplement utiliser
this.session
dans session_end
ou un code supplémentaire est nécessaire?Aussi, si plusieurs utilisateurs sont connectés au site. puis
this
individuellement reportez-vous à chaque demande de droit?OriginalL'auteur Rob Cooper | 2009-01-21
Vous devez vous connecter pour publier un commentaire.
Mondiale.asax implémente HttpApplication - qui est ce que vous parlez quand vous appelez ce de l'intérieur.
La documentation MSDN pour HttpApplication a des détails sur la façon dont vous pouvez obtenir de celui-ci dans un HttpHandler par exemple, et ensuite obtenir l'accès aux différentes propriétés.
CEPENDANT
Votre application peut créer plusieurs instances de HttpApplication pour gérer les demandes parallèles, et ces instances peuvent être ré-utilisé, donc il suffit de la ramasser en quelque sorte ne va pas garantir que vous avez le droit.
Moi aussi, je voudrais également ajouter une note de prudence - si votre application se bloque, il n'y a aucune garantie que session_end va être appelé, et vous aurez perdu toutes les données sur l'ensemble des sessions, clairement pas une bonne chose.
Je suis d'accord que la journalisation sur chaque page est probablement pas une bonne idée, mais peut-être une maison de transition, avec quelques asynchrone journalisation de passe - vous le feu de détails à une classe de log, que chaque maintenant et puis enregistre les détails vous sont après toujours pas à 100% de solides, si l'application se bloque, mais vous avez moins de chance de tout perdre.
OriginalL'auteur Zhaph - Ben Duguid
Pour répondre à la question initiale de mieux:
Fond
Chaque demande de page lance une nouvelle
Session
objet et pour effet de gonfler à partir de votre session magasin. Pour ce faire, il utilise les cookies fournis par le client ou un chemin spécial de construire (pour cookieless sessions). Avec cet identifiant de session, il consulte la session magasin et désérialise (c'est pourquoi tous les fournisseurs, mais InProc besoin d'être Sérialisable) la nouvelle session de l'objet.Dans le cas de la InProc fournisseur, simplement vous tend la référence stockée dans les
HttpCache
identifié par l'identifiant de session. C'est pourquoi le InProc fournisseur de gouttes d'état de session lorsque leAppDomain
est recyclé (et aussi pourquoi plusieurs serveurs web ne peut pas partager InProc l'état de session.Nouvellement créé et gonflé objet est coincé dans le
Context.Items
collection de sorte qu'il est disponible pour la durée de la demande.Toutes les modifications que vous apportez à la
Session
objet sont ensuite persisté jusqu'à la fin de la demande pour la session de banque par la sérialisation (ou le cas de InProc, leHttpCache
entrée est mise à jour).Depuis
Session_End
feux sans une requête en cours dans-mouche, leSession
objet est lancé l'ex-nilo, avec pas d'information disponible. Si vous utilisez InProc l'état de la session, la date d'expiration de laHttpCache
déclenche un événement de rappel dans votreSession_End
de l'événement, l'entrée de la session est disponible, mais il est encore une copie de ce dernier a été stockée dans leHttpContext.Cache
. Cette valeur est stockée à l'encontre de laHttpApplication.Session
propriété par une méthode interne (appeléProcessSpecialRequest
) où elle est disponible. Dans tous les autres cas, à l'interne, vient de laHttpContext.Current.Session
valeur.Votre réponse
Depuis le Session_End toujours les feux de contre null Contexte, vous devez TOUJOURS utiliser ce.Session et passer le HttpSessionState objet vers le bas de votre code de traçage. Dans tous les autres contextes, il est parfaitement bien pour en extraire des
HttpContext.Current.Session
puis passer dans le code de traçage. Ne PAS, cependant, laisser le traçage de code à atteindre pour le contexte de session.Ma réponse
Ne pas utiliser
Session_End
sauf si vous savez que la session de magasin, vous utilisez prend en chargeSession_End
, il ne si elle renvoietrue
deSetItemExpireCallback
. Le seul dans le magasin de boîte qui n'est leInProcSessionState
magasin. Il est possible d'écrire une session magasin qui ne mais la question de savoir qui va traiter leSession_End
est une sorte de ambiguë s'il existe plusieurs serveurs.OriginalL'auteur IDisposable
Je pense que vous avez déjà répondu à votre propre question: en général, la propriété de Session Mondiale.asax et HttpContext.Actuel.Session sont les mêmes (si il y a une demande en cours). Mais dans le cas d'un délai d'expiration de session, il n'y a pas de requête active et, par conséquent, vous ne pouvez pas utiliser HttpContext.Actuel.
Si vous souhaitez accéder à la session à partir de la méthode dite par Session_End, puis le passer en paramètre. Créer une version surchargée de la méthode Log (), qui prend une HttpSessionState comme paramètre, puis call Tracker.Journal(ce.Session) de la Session_End gestionnaire d'événement.
BTW: vous êtes conscient que vous ne pouvez pas compter sur la fin de la session de l'événement dans tous les cas? Il ne fonctionne que tant que vous avez l'état de la session en cours. Lors de l'utilisation de SQL server ou StateServer pour gérer l'état de la session, la session de fin de l'événement ne se déclenche pas.
OriginalL'auteur M4N
La
Session_End
événement est déclenché uniquement lorsque lasessionstate mode
est fixé àInProc
dans leWeb.config
fichier. Si le mode de session est fixé àStateServer
ouSQLServer
, l'événement n'est pas déclenché.utilisation
Session["SessionItemKey"]
pour obtenir la valeur de session.OriginalL'auteur Usha
D'accord, je suis dans le même problème pour suivre la session de l'activité. Au lieu d'utiliser session_end événement, j'ai implémenté l'interface IDisposable et destructeur pour mon sessiontracker classe. J'ai modifié la méthode dispose() pour enregistrer la session de l'activité à la DB. J'ai invoqué la méthode obj.Dispose() lorsque l'utilisateur clique sur le bouton de déconnexion. Si l'utilisateur a fermé le navigateur par erreur, puis GC appel du destructeur pendant le nettoyage des objets (pas immédiatement, mais pour sûr qu'il fera appel de cette méthode bout d'un certain temps). Le destructeur méthode interne exécuter la même méthode dispose() pour enregistrer les activités de session en DB.
-Shan
OriginalL'auteur
Session est disponible dans votre Global.asax fichier, lors de l'événement Session_Start. Peut-être attendre jusqu'à ce point pour faire des trucs?
OriginalL'auteur brumScouse
Rappelez-vous que Session_End s'exécute lors de la session expire sans activité. Le navigateur n'est pas à l'origine de cet événement (car il est inactif), de sorte que la seule fois que vous obtenez l'événement lors de l'utilisation de la InProc fournisseur. Dans TOUT AUTRE fournisseur, cet événement se déclenche jamais.
Moral? N'utilisez pas de Session_End.
Donc, dire à quelqu'un qu'ils le font MAL, d'une manière QUI PEUT ÉCHOUER ÉTONNAMMENT, est une mauvaise réponse? Voir "Marteler Un Clou: Vieille Chaussure ou une Bouteille en Verre?" .gd/gSb1
Pour le record, je suis totalement d'accord avec le point principal de votre post, mais je pense personnellement qu'il n'a pas de contribuer à une "réponse" à la question elle-même.. "Ne pas utiliser" n'aide pas à mon humble avis.. "Ne pas utiliser par essayer ce" peut avoir été beaucoup plus utile.. 🙂
OriginalL'auteur IDisposable