сервер состояния c # поддерживает сеанс между машинами

StackOverflow https://stackoverflow.com/questions/1821937

  •  10-07-2019
  •  | 
  •  

Вопрос

Я уверен, что допустил какую-то болезненно очевидную ошибку (ы), которую я просто не могу увидеть.Я надеюсь, что кто-нибудь из вас сможет наставить меня на путь истинный.

I мое управление сеансами работает отлично, за исключением того, что если пользователь на одной машине вводит данные, пользователь, который запускает сеанс на другой машине, также повторно получит информацию о сеансе с первой.Не так уж хорошо.:(

Я называю свои сеансы так:

UserInfo userinfo = UserInfo.Session;

Мой сессионный класс mgt использует это:

static UserInfo userInfo;

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

Я считываю и записываю данные следующим образом.Я понимаю, что мог бы сериализовать весь класс, но, похоже, гораздо больше накладных расходов на сериализацию и десериализацию всего класса при каждом вызове класса, в отличие от простого захвата одного или двух элементов, которые мне нужны.

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

Спасибо за вашу помощь

Это было полезно?

Решение

1) Вы используете статические данные для своей UserInfo, что означает, что один экземпляр этого класса является общим для всех запросов, поступающих на ваш веб-сервер.

2) Вы храните не только значения в сеансе (который не используется пользователями), но также и в переменной экземпляра, которая в этом случае БУДЕТ разделена между пользователями.

Таким образом, значение _latitude вызывает у вас эту проблему. Простое решение:

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

Лучшая, более тестируемая версия:

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

Во втором случае в запросе вы просто создаете новый экземпляр HttpSessionStateWrapper (используя текущий сеанс) и передайте его экземпляру UserInfo. Когда вы тестируете, вы можете просто передать имитацию Wrapper.

Независимо от того, что экземпляр UserInfo не должен быть общим для сеансов, он должен записывать и читать непосредственно из сеанса. Не пытайтесь преждевременно оптимизировать вещи, сохраняя локальные версии значений сеанса. Вы не экономите время и просто открываете себя для ошибок.

Другие советы

Это происходит потому, что вы храните информацию о своем пользователе в статическом поле.Статические экземпляры являются общими для всех запросов и существуют в течение всего срока службы вашего приложения.

Другими словами, все ваши пользователи получат один и тот же экземпляр userInfo из userInfo.Session.

Чтобы исправить это, вы могли бы:

  • Сериализуйте весь класс в сеанс.Я не знаю, какие еще свойства у вас есть, но я бы предположил, что это не будет слишком большими накладными расходами.
  • Создайте экземпляр userInfo для каждого запроса, чтобы пользователь всегда считывал данные из нового экземпляра, который, в свою очередь, обновит свои значения из сеанса.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top