2010-06-08 18 views
0

Ok, j'ai cette classe web singleton qui utilise la session pour maintenir l'état. J'ai d'abord pensé que j'allais devoir manipuler les variables de session sur chaque "ensemble" afin que les nouvelles valeurs soient mises à jour dans la session. Cependant j'ai essayé de l'utiliser tel quel, et d'une manière ou d'une autre, il se souvient de l'état.Comment cette classe Web de type Singleton conserve-t-elle les données de session, même si la session n'est pas mise à jour dans les setters de propriétés?

Par exemple, si exécuter ce code sur une page:

UserContext.Current.User.FirstName = "Micah"; 

Et exécuter ce code dans un onglet de navigateur, FirstName est affiché correctement:

Response.Write(UserContext.Current.User.FirstName); 

Quelqu'un peut-il me dire (prouver) comment ces données sont persistées dans la session? Voici la classe:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

public class UserContext 
{ 
    private UserContext() { } 

    public static UserContext Current 
    { 
    get 
    { 
     if (System.Web.HttpContext.Current.Session["UserContext"] == null) 
     { 
     UserContext uc = new UserContext(); 
     uc.User = new User(); 
     System.Web.HttpContext.Current.Session["UserContext"] = uc; 
     } 

     return (UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 
    } 
    } 

    private string HospitalField; 
    public string Hospital 
    { 
    get { return HospitalField; } 
    set 
    { 
     HospitalField = value; 
     ContractField = null; 
     ModelType = null; 
    } 
    } 

    private string ContractField; 
    public string Contract 
    { 
    get { return ContractField; } 
    set 
    { 
     ContractField = value; 
     ModelType = string.Empty; 
    } 
    } 

    private string ModelTypeField; 
    public string ModelType 
    { 
    get { return ModelTypeField; } 
    set { ModelTypeField = value; } 
    } 

    private User UserField; 
    public User User 
    { 
    get { return UserField; } 
    set { UserField = value; } 
    } 

    public void DoSomething() 
    { 
    } 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public string FirstName { get; set; } 
} 

J'ajouté à une montre, et peut voir que la variable de session est sans aucun doute être mis quelque part:

(UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 

Dès qu'un setter est appelé la session var est mis à jour immédiatement:

set 
    { 
     HospitalField = value; //<--- here 
     ContractField = null; 
     ModelType = null; 
    } 

Répondre

2

L'instance UserContext est enregistrée en session avec cette ligne:

System.Web.HttpContext.Current.Session["UserContext"] = uc; 

Ce n'est pas un singleton. La propriété statique UserContext tente d'extraire une instance de Session et, si elle ne la trouve pas, crée une nouvelle instance et la stocke dans Session.

MISE À JOUR

Je peux voir comment récupérer la session var, ma confusion est autour de la façon dont la session var est définie.

Pour ajouter des précisions ci-dessous le commentaire de Micah: la première fois la propriété actuelle statique est accessible, une nouvelle instance UserContext est créé, sa propriété utilisateur est peuplée par une nouvelle instance de l'utilisateur, et l'instance UserContext est stockée en session. Les accès suivants à UserContext.Current (et donc à UserContext.Current.User) dans la même session accèdent tous à la même instance.

Si ce n'est toujours pas clair, je suggère de passer par un débogueur.

public static UserContext Current 
{ 
    get 
    { 
     // If Session does not yet contain a UserContext instance ... 
     if (System.Web.HttpContext.Current.Session["UserContext"] == null) 
     { 
      // ... then create and initialize a new UserContext instance ... 
      UserContext uc = new UserContext(); 
      uc.User = new User(); 
      // ... and store it in Session where it will be available for 
      // subsequent requests during the same session. 
      System.Web.HttpContext.Current.Session["UserContext"] = uc; 
     } 
     // By the time we get here, Session contains a UserContext instance, 
     // so return it. 
     return (UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 
    } 
} 
+0

Je peux voir comment la session var est récupérée, ma confusion est autour de la façon dont la session var est définie. Quand je cours UserContext.Current.User.FirstName = "Micah"; Je ne vois nulle part où il est remis dans la session var. La seule fois que la session est définie est quand elle crée une nouvelle instance sans données. –

+0

Je ne suis pas sûr si vous comprenez ce que je demande. Dès que le code appelle "HospitalField = value;" la session passe de nulle à être peuplée avec un nom d'hôpital. Avant que cette ligne s'exécute, tous les champs de la variable de session sont null. Où la session est-elle définie? Le seul endroit où le code définit la session var est lorsqu'il est rempli avec un nouvel objet avec des champs vides. –

+0

Lorsque vous appelez "UserContext.Current.Hospital = value;", le getter UserContext.Current est appelé en premier (et crée l'objet dans Session), puis le setter "Hospital" est appelé, après quoi l'objet a déjà été créé en session. Avez-vous essayé de passer par un débogueur? Vous devrez peut-être modifier vos paramètres de débogage VS afin qu'il apparaisse dans les propriétés pour voir ce qui se passe. – Joe

0

Et exécuter ce code dans un autre onglet du navigateur , FirstName est affiché correctement:

vous enregistrez dans la session. L'ouverture d'un nouvel onglet peut utiliser les mêmes informations de session que l'autre onglet (je ne suis pas certain de tous les navigateurs). Essayez d'ouvrir une nouvelle fenêtre de navigateur (pas seulement un onglet), et voyez ce qui se passe.

+0

Je reçois le même comportement avec une nouvelle fenêtre de navigateur. –

+0

Ma question est * comment * est-il enregistré en session. –

1

Joe a raison.Votre utilisation est: UserContext.Current.User.FirstName

Dans le getter de UserContext.Current, vous obtenez une référence à une partie de la mémoire qui réside dans l'objet de session dans asp.net. L'utilisation de l'un des setters devrait/devrait changer cette mémoire et si vous inspectez l'objet de session dans le débogueur ou sur les lignes de code suivantes, vous devriez voir les mêmes données que vous avez définies avec vos setters.

+0

Cela prend tout son sens. Et il est renvoyé en tant qu'objet casté, de sorte que les propriétés fortement typées peuvent être définies. –