Является ли этот метод доступа к сеансу ASP.NET безопасным для нескольких пользователей?

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

По сути, есть класс — обычно либо static, либо шаблон Singleton, в основном в зависимости от разработчика, который его написал, — хранящийся в App_Code.

Этот класс инкапсулирует доступ к текущему сеансу через свойства. Все эти свойства принимают форму:

public static class SessionHelper
{
    public static string SessionValue
    {
        get
        {
            object o = HttpContext.Current.Session["sessionValueName"];
            if (o == null)
            {
                // Replace the following with code to store & retrieve
                // a default value of the appropriate datatype.
                o = string.Empty;
                HttpContext.Current.Session["sessionValueName"] = o;
            }

            return o.ToString(); // or cast, ensure cast is valid & return.
        }
        set
        {
            HttpContext.Current.Session["sessionValueName"] = value;
        }
    }

    // Other properties, strongly-typed, as above.
}

(Они не являются статическими, если класс является синглтоном.)

Я видел проблемы со статическими данными на веб-сайтах в прошлом, в основном из-за того, что статические данные использовались для поддержания состояния для каждого сеанса. (Например, я видел статически объявленных «на пользователя» членов кода программной части. Это не мой код; моя команда была командой по очистке для компании, которая написала этот беспорядок.)

Однако, поскольку это всего лишь статическая запись в HttpContext.Current.Session, кажется, что она должна быть безопасной, поскольку принципиально ничем не отличается от класса Page, инкапсулирующего это в свойстве Session. Как я уже сказал, ни на одном другом сайте, над которым работала моя компания и который использовал этот шаблон, не было никаких проблем, включая довольно большие и очень активные базы пользователей. Но я хочу просто получить свежий взгляд.

Существуют ли потенциальные проблемы с несколькими пользователями, условия гонки или другие сбои/недостатки, которые конкретно могут вызвать повреждение сеанса в приведенном выше шаблоне?


person John Rudy    schedule 09.03.2010    source источник


Ответы (2)


Это безопасно. Тот факт, что вы обращаетесь к нему через какое-то статическое свойство или статический класс, совершенно не имеет значения. Это языковая абстракция. Поставщик сеанса отвечает за сопоставление запросов с их правильным сеансом... поэтому, если в этом нет ошибки, все в порядке.

person Bryan    schedule 10.03.2010

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

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

Вот почему я полагаюсь только на один ключ, используемый для хранения «моего сеанса» в сеансе ASP.NET. Затем все данные сеанса реализуются как обычные свойства объекта «мой сеанс».


Вот как выглядит мой подход:

public class MySession
{
    // private constructor
    private MySession() {}

    // Gets the current session.
    public static MySession Current
    {
      get
      {
        MySession session =
          (MySession)HttpContext.Current.Session["__MySession__"];
        if (session == null)
        {
          session = new MySession();
          HttpContext.Current.Session["__MySession__"] = session;
        }
        return session;
      }
    }

    // **** add your session properties here, e.g like this:
    public string Property1 { get; set; }
    public DateTime MyDate { get; set; }
    public int LoginId { get; set; }
}

Этот класс хранит один экземпляр самого себя в сеансе ASP.NET и позволяет вам получать доступ к свойствам сеанса безопасным для типов способом из любого класса, например, так:

int loginId = MySession.Current.LoginId;

string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;

DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;

Этот подход имеет несколько преимуществ:

  • это спасает вас от большого количества типов
  • вам не нужно использовать жестко заданные сеансовые ключи во всем приложении (например, Session["loginId"]
  • вы можете документировать элементы вашего сеанса, добавляя комментарии XML-документа к свойствам MySession
person M4N    schedule 09.03.2010
comment
+1, я думаю, что мы, как правило, на одной волне; Я не думаю, что мне было ясно, что это отдельный класс, и жестко закодированные ключи используются только в этом классе, так как весь доступ к сеансу проходит через этот класс. Я обновлю текст моего вопроса соответствующим образом. Тем не менее, мне нравится идея одного объекта в сеансе, которая является новой. :) - person John Rudy; 10.03.2010
comment
Хмммм... Мне не очень нравится такой подход. Это означает, что вы получаете/устанавливаете ВСЕ каждый раз, когда получаете доступ к одному элементу сеанса. Это может быть дорогостоящей операцией, в зависимости от вашего поставщика сеансов. - person Bryan; 10.03.2010
comment
@Bryan: это хороший момент! Но обычно мы стараемся, чтобы состояние сеанса было как можно меньше, и разница между получением одного объекта, содержащего 20 значений (как в моем подходе), или получением 5 или 10 значений по отдельности, вероятно, не будет большой. - person M4N; 10.03.2010