Que dois-je faire si la session ASP.NET actuelle est nulle?

125

Dans mon application Web, je fais quelque chose comme ceci pour lire les variables de session:

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

Je comprends pourquoi il est important de vérifier pourquoi HttpContext.Current.Session ["MyVariable"] est nul (la variable n'a peut-être pas encore été stockée dans la session ou la session a été réinitialisée pour diverses raisons), mais pourquoi dois-je vérifier si HttpContext.Current.Sessionest nul?

Je crois comprendre que la session est créée automatiquement par ASP.NET, par conséquent HttpContext.Current.Session ne doit jamais être nul. Cette hypothèse est-elle correcte? S'il peut être nul, cela signifie-t-il que je devrais également le vérifier avant d'y stocker quelque chose:

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?
}
Anthony
la source
ASP.NET WebApi aura un comportement différent, vous pouvez le vérifier sur Accès à la session à l'aide de l'API Web ASP.NET
Tiago Gouvêa

Réponses:

158

Oui, l'objet Session peut être nul, mais uniquement dans certaines circonstances, que vous ne rencontrerez que rarement:

Si vous n'avez que du code dans les pages, vous ne rencontrerez pas cela. La plupart de mon code ASP .NET utilise Session sans vérifier la valeur null à plusieurs reprises. Il faut cependant penser à cela si vous développez un IHttpModule ou si vous êtes dans les détails plus granuleux d'ASP .NET.

Éditer

En réponse au commentaire: La disponibilité ou non de l'état de session dépend de l'exécution ou non de l'événement AcquireRequestState pour la demande. C'est là que le module d'état de session fait son travail en lisant le cookie de session et en trouvant l'ensemble de variables de session approprié pour vous.

AcquireRequestState s'exécute avant que le contrôle ne soit transféré à votre page. Donc, si vous appelez d'autres fonctionnalités, y compris des classes statiques, à partir de votre page, tout devrait bien se passer.

Si certaines classes effectuent une logique d'initialisation au démarrage, par exemple sur l'événement Application_Start ou à l'aide d'un constructeur statique, l'état de session peut ne pas être disponible. Tout se résume à savoir s'il existe une demande en cours et que AcquireRequestState a été exécuté.

De plus, si le client a désactivé les cookies, l'objet Session sera toujours disponible - mais à la demande suivante, l'utilisateur reviendra avec une nouvelle Session vide. Cela est dû au fait que le client reçoit un Statebag Session s'il n'en a pas déjà un. Si le client ne transporte pas le cookie de session, nous n'avons aucun moyen d'identifier le client comme étant le même, de sorte qu'il se verra remettre une nouvelle session encore et encore.

driis
la source
6
Juste une mise à jour rapide que j'ai trouvée aujourd'hui. La session n'est pas disponible sur le constructeur de page! Uniquement sur l'événement Init ou après cela.
Nuno Agapito
Je viens de rencontrer un HttpContext.Current.Session == null est un code appelé par un événement Page Load d'une page maître. Apparemment, cela peut se produire dans le contexte d'une page. Si j'inspecte l'objet HttpContext.Current, la plupart de ses membres sont initialisés, mais CurrentNotification et IsPostNotification génèrent une erreur: {System.PlatformNotSupportedException}. Quelle qu'en soit la cause, ce problème ne s'est pas produit en production, où il existe depuis des années. La plate-forme est Windows Server 2003 R2 SP2, l'application a le framework cible .Net 3.5 et s'exécute dans IIS avec l'état de session activé.
R. Schreurs
J'ai également constaté que, lorsque IIS sert une demande directe pour un fichier de ressources qui existe sur le disque, comme une feuille de style, HttpContext.Current.Sessionpeut être nul pour coder dans `Application_AcquireRequestState '. Cependant, la requête de la page elle-même rend l'objet de session disponible pour y coder. C'est au moins sous MVC.NET 4.
ingrédient_15939
Je pense que cela pourrait également être nul si vous êtes dans une action MVC mise en cache en sortie.
user2173353
40

L'affirmation suivante n'est pas entièrement exacte:

"Donc, si vous appelez d'autres fonctionnalités, y compris des classes statiques, à partir de votre page, ça devrait aller"

J'appelle une méthode statique qui fait référence à la session via HttpContext.Current.Session et elle est nulle. Cependant, j'appelle la méthode via une méthode de service Web via ajax en utilisant jQuery.

Comme je l'ai découvert ici, vous pouvez résoudre le problème avec un simple attribut sur la méthode ou utiliser l'objet de session de service Web:

Il y a cependant une astuce, pour accéder à l'état de session dans une méthode Web, vous devez activer la gestion de l'état de session comme ceci:

[WebMethod (EnableSession = true)]

En spécifiant la valeur EnableSession, vous aurez désormais une session gérée avec laquelle jouer. Si vous ne spécifiez pas cette valeur, vous obtiendrez un objet Session nul et vous rencontrerez probablement des exceptions de référence nulles en essayant d'accéder à l'objet session.

Merci à Matthew Cozier pour la solution.

Je pensais juste ajouter mes deux cents.

Ed

Ed Bishop
la source
1
merci Ed, Session apparaissait comme nulle dans la méthode Web - l'ajout de cela l'a corrigé. +1
fusi
1
Eh bien, lorsque vous appelez un service Web, vous utilisez une autre demande que pour la page, donc cette déclaration est toujours correcte, OMI.
driis
Documents MSDN ici - the default value is false. Fonctionne comme un charme.
Benjineer
22

Si votre instance Session est nulle et que vous êtes dans un fichier 'ashx', implémentez simplement l'interface 'IRequiresSessionState'.

Cette interface n'a aucun membre, il vous suffit donc d'ajouter le nom de l'interface après la déclaration de classe (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState
mathijsuitmegen
la source
Merci beaucoup, la session était nulle dans ma classe de connexion. Quand j'ai ajouté ce code à mon gestionnaire ashx, la session a également tourné sur ma classe
Ateş Danış
Je pense que cela répond assez bien à la question. Merci beaucoup.
Sachin Joseph
2

Articles techniques ASP.NET

Réduire tout Résumé: dans ASP.NET, chaque page Web dérive de la classe System.Web.UI.Page. La classe Page agrège une instance de l'objet HttpSession pour les données de session. La classe Page expose différents événements et méthodes de personnalisation. En particulier, la méthode OnInit est utilisée pour définir l'état d'initialisation de l'objet Page. Si la demande ne contient pas de cookie de session, un nouveau cookie de session sera émis au demandeur.

ÉDITER:

Session: un concept pour les débutants

Résumé: la session est créée lorsque l'utilisateur envoie une première demande au serveur pour n'importe quelle page de l'application Web, l'application crée la session et renvoie l'ID de session à l'utilisateur avec la réponse et est stockée dans l'ordinateur client sous forme de petit cookie . Donc idéalement la "machine qui a désactivé les cookies, les informations de session ne seront pas stockées".

adatapost
la source
2

Dans mon cas, a ASP.NET State Serviceété arrêté. La modification Startup typede Automaticet le démarrage manuel du service pour la première fois a résolu le problème.

Eric
la source