Який найкращий спосіб визначити, що змінна сеансу є нульовою чи порожньою в 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;
 }

Відповіді:


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.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
Ви не можете цього зробити ... Сесія ["змінна"] є Об'єктом, а потім компілятор перетворить її на Рядок, оскільки sSession є Рядок, якщо Сесія ["змінна"] не існує, він видає виняток !
balexandre

Ви абсолютно праві. Я оновив код, щоб передати рядок, якщо Session не має значення null.
Елі,

14

Це може зробити речі більш елегантними, якщо обернути їх у власність.

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

тоді ви можете розглядати це як рядок.

if( String.IsNullOrEmpty( MySessionVar ) )
{
   // do something
}

Це те, що я роблю, набагато полегшує доступ до сеансів у програмі. Я схильний створювати класи для даних та статичних властивостей, які виконують усі роботи з нульовою перевіркою.
Роб Купер

Що робити, якщо ви зберігаєте в сеансі об’єкт, а не просто рядок?
Аарон Палмер,

1
Побачте мою відповідь, використання дженериків забезпечує безпеку типу при зберіганні інших об’єктів.
Роб Купер,

Вибачте, чи правильна частина "Сесія (" "? Я отримую помилки.
Ісус Замора

Це було б у VB. :) змінено на квадратні дужки.
Greg Ogle

8

Позначення "як" у c # 3.0 дуже чітке. Оскільки всі сеансові змінні є обнулюваними об'єктами, це дозволяє вам захопити значення та помістити його у власну набрану змінну, не турбуючись про виняток. Більшість об’єктів можна обробляти таким чином.

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

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

Якщо вам потрібна ненульована набрана змінна, ви можете використати 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);

Мені подобається варіант дженериків, але це здається надмірним, якщо ви не сподіваєтеся, що це потрібно всюди. Метод розширень може бути змінений, щоб спеціально розширити об'єкт Session, щоб він мав "безпечний" параметр отримання, такий як 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 із сильно набраними властивостями для елементів у сеансі. Код, який отримує доступ до цих властивостей, перевіряє наявність недійсності та робить кастинг відповідного типу. Найприємніше в цьому полягає в тому, що всі мої предмети, пов’язані з сесіями, зберігаються в одному місці. Мені не потрібно турбуватися про використання різних ключів у різних частинах коду (і про те, чому це не працює). І завдяки введенню залежності та глузуванню я можу повністю перевірити це за допомогою модульних тестів. Якщо дотримується принципів СУХОГО, а також дозволяє мені визначити обґрунтовані значення за замовчуванням.

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

1

Я також люблю обертати змінні сеансу у властивостях. Тут установлювачі є тривіальними, але я люблю писати методи get, щоб вони мали лише одну точку виходу. Для цього я зазвичай перевіряю наявність нуля та встановлюю значення за замовчуванням перед тим, як повертати значення змінної сеансу. Щось на зразок цього:

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

}


1

Цей метод також не передбачає, що об'єкт у змінній Session є рядком

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 (цей об'єкт введення) {return input == null; }
Джеймс Керран,

Ви повинні бути обережними з методами розширення.
Кріс Пічман

1
Чому я повинен бути обережним з методами розширення?
Майкл Кніскерн,

чому ви просто не використовуєте x == null або x! = null?
Бенуа

0

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

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.