Domanda

Sono sicuro di aver commesso alcuni errori dolorosamente ovvi che non riesco proprio a vedere. Spero che uno di voi mi possa chiarire.

La mia gestione della sessione funziona perfettamente, tranne per il fatto che se un utente su una macchina immette dati, un utente che avvia una sessione su un'altra macchina recupererà anche le informazioni sulla sessione dalla prima. Non così buono. : (

Chiamo le mie sessioni in questo modo:

UserInfo userinfo = UserInfo.Session;

La mia sessione mgt class usa questo:

static UserInfo userInfo;

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

Ho letto e scritto i dati in questo modo. Mi rendo conto che potrei serializzare l'intera classe, ma mi sembra molto più costoso serializzare e deserializzare un'intera classe ogni volta che la classe viene chiamata invece di prendere solo uno o due elementi di cui ho bisogno.

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); }
    }

Grazie per l'aiuto

È stato utile?

Soluzione

1) Stai utilizzando la statica per UserInfo, il che significa che una singola istanza di questa classe è condivisa tra tutte le richieste che arrivano al tuo server web.

2) Non stai solo memorizzando valori nella sessione (che non è condivisa tra gli utenti) ma anche in una variabile di istanza, che in questo caso sarà condivisa tra gli utenti.

Quindi il valore di _latitude ti sta causando questo problema. Una soluzione semplice è questa:

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

Una versione migliore e più testabile sarebbe:

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; }
    }
}

Nella seconda istanza, all'interno di una richiesta è sufficiente costruire una nuova istanza di HttpSessionStateWrapper (utilizzando la sessione corrente) e passalo all'istanza UserInfo. Quando esegui il test, puoi semplicemente passare un Wrapper finto.

Indipendentemente da ciò, l'istanza UserInfo non dovrebbe essere condivisa tra le sessioni e dovrebbe scrivere e leggere direttamente dalla sessione. Non tentare di ottimizzare prematuramente le cose mantenendo le versioni locali dei valori della sessione. Non stai risparmiando tempo e ti stai solo aprendo ai bug.

Altri suggerimenti

Ciò accade perché si memorizzano le informazioni dell'utente in un campo statico. Le istanze statiche sono condivise tra tutte le richieste e durano per l'intera vita dell'applicazione.

In altre parole, tutti gli utenti riceveranno la stessa istanza UserInfo da UserInfo.Session.

Per risolvere questo problema puoi:

  • Serializza l'intera classe in sessione. Non so quali altre proprietà hai, ma immagino che non sarebbe un sovraccarico.
  • Crea un'istanza di UserInfo per richiesta, in modo che l'utente legga sempre da una nuova istanza, che a sua volta aggiornerà i suoi valori dalla Sessione.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top