Как лучше всего определить, что переменная сеанса пуста или пуста в C #?

79

Как лучше всего проверить наличие переменной сеанса в ASP.NET C #?

Мне нравится использовать String.IsNullOrEmpty()произведения для строк, и мне было интересно, есть ли аналогичный метод для Session. В настоящее время я знаю только один способ:

 var session;
 if (Session["variable"] != null)
 {
     session = Session["variable"].ToString();
 }
 else
 {
     session = "set this";
     Session["variable"] = session;
 }
Craigmoliver
источник

Ответы:

114

Чтобы следовать из того, что сказали другие. Я предпочитаю два слоя:

Основной слой. Это внутри библиотеки DLL, которая добавляется почти во все проекты веб-приложений . Здесь у меня есть класс SessionVars, который выполняет ворчание для получателей / установщиков состояния сеанса. Он содержит следующий код:

public class SessionVar
{
    static HttpSessionState Session
    {
        get
        {
            if (HttpContext.Current == null)
                throw new ApplicationException("No Http Context, No Session to Get!");

            return HttpContext.Current.Session;
        }
    }

    public static T Get<T>(string key)
    {
        if (Session[key] == null)
            return default(T);
        else
            return (T)Session[key];
    }

    public static void Set<T>(string key, T value)
    {
        Session[key] = value;
    }
}

Обратите внимание на общие для получения любого типа.

Затем я также добавляю Getters / Setters для определенных типов, особенно string, поскольку я часто предпочитаю работать с string.Empty, а не с null для переменных, представленных пользователям.

например:

public static string GetString(string key)
{
    string s = Get<string>(key);
    return s == null ? string.Empty : s;
}

public static void SetString(string key, string value)
{
    Set<string>(key, value);
}

И так далее...

Затем я создаю оболочки, чтобы абстрагироваться от этого и доводить до модели приложения. Например, если у нас есть данные о клиенте:

public class CustomerInfo
{
    public string Name
    {
        get
        {
            return SessionVar.GetString("CustomerInfo_Name");
        }
        set
        {
            SessionVar.SetString("CustomerInfo_Name", value);
        }
    }
}

Вы правильно поняли? :)

ПРИМЕЧАНИЕ: Просто подумал, когда добавлял комментарий к принятому ответу. Всегда обеспечивайте сериализацию объектов при их сохранении в сеансе при использовании сервера состояний. Может быть слишком легко попытаться сохранить объект с помощью универсальных шаблонов, когда он находится на веб-ферме, и он быстро развивается. Я развертываю на работе веб-ферму, поэтому добавил в свой код на уровне ядра проверки, чтобы убедиться, что объект сериализуем, еще одно преимущество инкапсуляции методов получения и установки сеанса :)

Роб Купер
источник
Отличный подход! Я давно использую нечто подобное, но не использовал дженерики. Это позволяет избежать множества проблем, когда разные разработчики создают похожие переменные сеанса.
DOK
Как я могу обработать исключения, если "выбросить новое исключение ApplicationException (" Нет контекста HTTP, нет сеанса для получения! ");" выполняется ?, я не понимаю, что такое автоматически реализуемые свойства, в какой части кода я могу получить исключение, когда это произойдет.
Marztres
Хороший подход. У меня проблемы с реализацией этого в библиотеке классов C #. Я не могу разрешить ссылки на HttpSessionState/ HttpContext. Приходилось ли вам устанавливать библиотеку MVC в DLL, чтобы импортировать правильные пространства имен?
seebiscuit
18

Это в значительной степени то, как вы это делаете. Однако вы можете использовать более короткий синтаксис.

sSession = (string)Session["variable"] ?? "set this";

Это говорит о том, что если переменные сеанса равны нулю, установите sSession на «установить это»

Эли
источник
1
вы не можете этого сделать ... Session ["переменная"] - это объект, и компилятор затем преобразует его в String, потому что sSession является String, если Session ["переменная"] не существует, он выдает исключение !
balexandre
Вы абсолютно правы. Я обновил код, чтобы привести строку, если сеанс не равен нулю.
Ely
14

Обернуть его в свойство может сделать вещи более элегантными.

string MySessionVar
{
   get{
      return Session["MySessionVar"] ?? String.Empty;
   }
   set{
      Session["MySessionVar"] = value;
   }
}

тогда вы можете рассматривать его как строку.

if( String.IsNullOrEmpty( MySessionVar ) )
{
   // do something
}
Грег Огл
источник
Это то, что я делаю, значительно упрощает доступ к переменным сеанса в приложении. Я стараюсь создавать классы для данных и статические свойства, которые выполняют всю работу по проверке нуля.
Роб Купер,
Что, если вы храните в сеансе объект, а не только строку?
Аарон Палмер,
1
См. Мой ответ, использование дженериков обеспечивает безопасность типов при хранении других объектов.
Роб Купер,
Простите, часть "Сессия (" "верна? Я получаю ошибки.
Хесус Замора,
Было бы на VB. :) заменены на квадратные скобки.
Грег Огл
8

Обозначение «as» в C # 3.0 очень чистое. Поскольку все переменные сеанса являются объектами, допускающими значение NULL, это позволяет вам получить значение и поместить его в свою собственную типизированную переменную, не беспокоясь о том, чтобы вызвать исключение. Таким образом можно обращаться с большинством объектов.

string mySessionVar = Session["mySessionVar"] as string;

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

Если вам нужна типизированная переменная, не допускающая значения NULL, вы можете использовать TryParse для ее получения.

int mySessionInt;
if (!int.TryParse(mySessionVar, out mySessionInt)){
   // handle the case where your session variable did not parse into the expected type 
   // e.g. mySessionInt = 0;
}
Аарон Палмер
источник
2

На мой взгляд, самый простой и понятный и легко читаемый способ сделать это:

 String sVar = (string)(Session["SessionVariable"] ?? "Default Value");

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

Например (совершенно надуманный пример, но он показывает суть):

 DateTime sDateVar = (datetime)(Session["DateValue"] ?? "2010-01-01");
 Int NextYear = sDateVar.Year + 1;
 String Message = "The Procrastinators Club will open it's doors Jan. 1st, " +
                  (string)(Session["OpeningDate"] ?? NextYear);

Мне нравится вариант Generics, но он кажется излишним, если вы не ожидаете, что он понадобится повсюду. Метод расширения может быть изменен, чтобы специально расширить объект сеанса так, чтобы он имел «безопасный» параметр получения, например Session.StringIfNull («SessionVar») и Session [«SessionVar»] = «myval»; Это нарушает простоту доступа к переменной через Session ["SessionVar"], но это чистый код, и он по-прежнему позволяет проверять значение null или строку, если вам это нужно.

Джон Фолкнер
источник
1

Проверка ничего / Null - это способ сделать это.

Работа с типами объектов - не лучший вариант. Объявите строгий тип и попытайтесь привести объект к правильному типу. (И используйте подсказку приведения или преобразование)

 private const string SESSION_VAR = "myString";
 string sSession;
 if (Session[SESSION_VAR] != null)
 {
     sSession = (string)Session[SESSION_VAR];
 }
 else
 {
     sSession = "set this";
     Session[SESSION_VAR] = sSession;
 }

Извините за синтаксические нарушения, я ежедневный VB'er

Стинги Джек
источник
1

Обычно я создаю SessionProxy со строго типизированными свойствами для элементов в сеансе. Код, который обращается к этим свойствам, проверяет их значение на null и выполняет приведение к правильному типу. Приятно то, что все элементы, связанные с сеансом, хранятся в одном месте. Мне не нужно беспокоиться об использовании разных ключей в разных частях кода (и удивляться, почему это не работает). А с внедрением зависимостей и издевательством я могу полностью протестировать его с помощью модульных тестов. Если следует принципам DRY, а также позволяет мне определять разумные значения по умолчанию.

public class SessionProxy
{
    private HttpSessionState session; // use dependency injection for testability
    public SessionProxy( HttpSessionState session )
    {
       this.session = session;  //might need to throw an exception here if session is null
    }

    public DateTime LastUpdate
    {
       get { return this.session["LastUpdate"] != null
                         ? (DateTime)this.session["LastUpdate"] 
                         : DateTime.MinValue; }
       set { this.session["LastUpdate"] = value; }
    }

    public string UserLastName
    {
       get { return (string)this.session["UserLastName"]; }
       set { this.session["UserLastName"] = value; }
    }
}
tvanfosson
источник
1

Мне также нравится заключать переменные сеанса в свойства. Сеттеры здесь тривиальны, но мне нравится писать методы get, чтобы у них была только одна точка выхода. Для этого я обычно проверяю значение null и устанавливаю для него значение по умолчанию, прежде чем возвращать значение переменной сеанса. Что-то вроде этого:

string Name
{
   get 
   {
       if(Session["Name"] == Null)
           Session["Name"] = "Default value";
       return (string)Session["Name"];
   }
   set { Session["Name"] = value; }
}

}

Руна Гримстад
источник
1

Этот метод также не предполагает, что объект в переменной сеанса является строкой

if((Session["MySessionVariable"] ?? "").ToString() != "")
    //More code for the Code God

Таким образом, в основном заменяет нулевую переменную пустой строкой перед преобразованием ее в строку, поскольку ToStringявляется частью Objectкласса

Сарфарааз
источник
0

Если вы знаете, что это строка, вы можете использовать функцию String.IsEmptyOrNull ().

Кевин Панг
источник
0

Вы используете .NET 3.5? Создайте метод расширения IsNull:

public static bool IsNull(this object input)
{
    input == null ? return true : return false;
}

public void Main()
{
   object x = new object();
   if(x.IsNull)
   {
      //do your thing
   }
}
Майкл Книскерн
источник
1
Это можно было бы написать: public static bool Is (this object input) {return input == null; }
Джеймс Карран,
Будьте осторожны с методами расширения.
Крис Питчманн,
1
Почему я должен быть осторожен с методами расширения?
Майкл Книскерн,
почему бы вам просто не использовать x == null или x! = null?
Бенуа
0

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

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
Якуп Ад
источник