Question

Je suis sûr d’avoir commis des erreurs douloureusement évidentes que je ne peux tout simplement pas voir. J'espère que l'un de vous pourra me mettre au clair.

La gestion de session fonctionne parfaitement, sauf que si un utilisateur d'une machine entre des données, un utilisateur qui démarre une session sur une autre machine récupérera également les informations de la session à partir de la première. Pas si bon. : (

J'appelle mes sessions comme suit:

UserInfo userinfo = UserInfo.Session;

Ma classe de gestion de session utilise ceci:

static UserInfo userInfo;

static public UserInfo Session
{
    get
    {
        if (userInfo == null)
        {
            userInfo = new UserInfo();
            userInfo.ResetSessionTime();
        }
        return userInfo;
    }
}

Je lis et écris les données comme ceci. Je me rends compte que je pourrais sérialiser la classe entière, mais il me semble que cela prend plus de temps de sérialiser et de désérialiser une classe entière chaque fois que la classe est appelée, au lieu de simplement saisir le ou les deux éléments dont j'ai besoin.

Decimal _latitude;
private String SessionValue(String sKey, String sValue, String sNewValue)
    {
        String sRetVal = "";
        if (sNewValue == null)//not wanting to update anything
        {
            if (sValue == null)//there is no existing value
            {
                sRetVal = (String)System.Web.HttpContext.Current.Session[sKey];
            }
            else
            {
                sRetVal = sValue;
            }
        }
        else
        {
            System.Web.HttpContext.Current.Session[sKey] = sNewValue;
            sRetVal = sNewValue;
        }
        return sRetVal;
    }



    public Decimal Latitude
    {
        get { return SessionValue("Latitude", _latitude); }
        set { _latitude = SessionValue("Latitude", _latitude, value); }
    }

Merci de votre aide

Était-ce utile?

La solution

1) Vous utilisez des statistiques pour votre UserInfo, ce qui signifie qu'une seule instance de cette classe est partagée entre toutes les demandes arrivant sur votre serveur Web.

2) Vous stockez non seulement des valeurs dans la session (qui n'est pas partagée entre les utilisateurs), mais également dans une variable d'instance, qui dans ce cas SERA partagée entre les utilisateurs.

La valeur de _latitude vous cause donc ce problème. Une solution simple est la suivante:

public class Userinfo
{
    public Decimal Latitude
    {
        get { return System.Web.HttpContext.Current.Session["Latitude"]; }
        set { System.Web.HttpContext.Current.Session["Latitude"] = value; }
    }
}

Une meilleure version, plus testable, serait:

public class UserInfo
{
    private HttpSessionStateWrapper _session;
    public UserInfo(HttpSessionStateWrapper session)
    ( 
       // throw if null etc
       _session = session;
    )

    public Decimal Latitude
    {
        get { return _session["Latitude"]; }
        set { _session["Latitude"] = value; }
    }
}

Dans le second cas, dans une requête, vous venez de construire une nouvelle instance de HttpSessionStateWrapper (à l'aide de la session en cours) et transmettez-le à l'instance UserInfo. Lorsque vous testez, vous pouvez simplement passer une maquette d’emballage.

Quoi qu'il en soit, l'instance UserInfo ne doit pas être partagée entre les sessions, elle doit écrire et lire directement à partir de la session. N'essayez pas d'optimiser prématurément les choses en conservant les versions locales de vos valeurs de session. Vous ne gagnez pas de temps et vous vous exposez à des bugs.

Autres conseils

Cela se produit parce que vous stockez vos informations utilisateur dans un champ statique. Les instances statiques sont partagées entre toutes les demandes et durent toute la vie de votre application.

En d'autres termes, tous vos utilisateurs obtiendront la même instance UserInfo à partir de UserInfo.Session.

Pour résoudre ce problème, vous pouvez:

  • Sérialiser la classe entière en session. Je ne sais pas quelles autres propriétés vous possédez, mais j’imagine que ce ne serait pas une surcharge.
  • Créez une instance de UserInfo par requête, de sorte que l'utilisateur lise toujours à partir d'une nouvelle instance, ce qui actualisera ses valeurs à partir de la session.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top