Jaki jest najlepszy sposób określenia, że ​​zmienna sesji jest null lub pusta w C #?


79

Jaki jest najlepszy sposób sprawdzenia istnienia zmiennej sesji w ASP.NET C #?

Lubię używać String.IsNullOrEmpty()worków dla ciągów i zastanawiałem się, czy istnieje podobna metoda dla Session. Obecnie jedyny znany mi sposób to:

 var session;
 if (Session["variable"] != null)
 {
     session = Session["variable"].ToString();
 }
 else
 {
     session = "set this";
     Session["variable"] = session;
 }

Odpowiedzi:


114

Kontynuacja tego, co powiedzieli inni. Zwykle mam dwie warstwy:

Warstwa rdzeniowa. Znajduje się w bibliotece DLL, która jest dodawana do prawie wszystkich projektów aplikacji sieci Web . W tym mam klasę SessionVars, która wykonuje podstawową pracę dla pobierających / ustawiających stan sesji. Zawiera kod podobny do następującego:

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

Zwróć uwagę na ogólne zasady uzyskiwania dowolnego typu.

Następnie dodaję również Getters / Setters dla określonych typów, zwłaszcza stringów, ponieważ często wolę pracować z string.Empty zamiast null dla zmiennych prezentowanych Użytkownikom.

na przykład:

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

I tak dalej...

Następnie tworzę opakowania, aby to wyodrębnić i przenieść do modelu aplikacji. Na przykład, jeśli mamy dane klienta:

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

Masz rację? :)

UWAGA: Właśnie pomyślałem, dodając komentarz do zaakceptowanej odpowiedzi. Zawsze upewnij się, że obiekty można serializować podczas przechowywania ich w sesji podczas korzystania z serwera stanu. Próba zapisania obiektu przy użyciu typów generycznych na farmie internetowej może być zbyt łatwa i szybko się rozwija. Wdrażam na farmie internetowej w pracy, więc dodałem kontrole do mojego kodu w warstwie podstawowej, aby zobaczyć, czy obiekt jest możliwy do serializacji, kolejna korzyść z hermetyzowania metod pobierających i ustawiających sesje :)


Świetne podejście! Używam czegoś podobnego przez długi czas, ale nie włączyłem generyków. Pozwala to uniknąć wielu problemów związanych z tworzeniem przez różnych programistów podobnych zmiennych sesji.
DOK

Jak mogę to zrobić dla obsługi wyjątków, jeśli "zgłoszenie nowego ApplicationException (" Brak kontekstu HTTP, brak sesji do pobrania! ");" jest wykonywany?, jestem mylący co do właściwości zaimplementowanych automatycznie, w której część kodu mogę uzyskać wyjątek, gdy wystąpi.
Marztres,

Niezłe podejście. Mam problem z zaimplementowaniem tego w bibliotece klas C #. Nie mogę rozwiązać odwołań do HttpSessionState/ HttpContext. Czy musisz zainstalować bibliotekę MVC w bibliotece DLL, aby zaimportować odpowiednie przestrzenie nazw?
seebiscuit

18

Tak właśnie robisz. Istnieje jednak krótsza składnia, której możesz użyć.

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

To znaczy, że jeśli zmienne sesji mają wartość null, ustaw sSession na „ustaw to”


1
nie możesz tego zrobić ... Session ["zmienna"] jest obiektem i kompilator następnie przekonwertuje go na łańcuch, ponieważ sSession jest ciągiem znaków, jeśli sesja ["zmienna"] nie istnieje, zgłasza wyjątek !
balexandre

Masz całkowitą rację. Zaktualizowałem kod, aby rzutował ciąg, jeśli Session nie jest null.
Ely,

14

Może sprawić, że rzeczy będą bardziej eleganckie, jeśli zostaną umieszczone w nieruchomości.

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

wtedy możesz traktować go jako ciąg.

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

To, co robię, znacznie ułatwia dostęp do zmiennych sesji w aplikacji. Zwykle tworzę klasy dla danych i właściwości statyczne, które wykonują całą pracę podstawową sprawdzania zerowego.
Rob Cooper

Co się stanie, jeśli przechowujesz obiekt w sesji, a nie tylko ciąg?
Aaron Palmer

1
Zobacz moją odpowiedź, użycie typów ogólnych umożliwia bezpieczeństwo typów podczas przechowywania innych obiektów.
Rob Cooper

Przepraszam, czy część „Sesja” jest poprawna? Otrzymuję błędy.
Jesus Zamora,

Byłoby w VB. :) zmieniono na nawiasy kwadratowe.
Greg Ogle

8

Notacja „as” w języku c # 3.0 jest bardzo czysta. Ponieważ wszystkie zmienne sesji są obiektami dopuszczającymi wartość null, umożliwia to pobranie wartości i umieszczenie jej we własnej zmiennej wpisanej bez obawy o rzucenie wyjątku. W ten sposób można obsługiwać większość obiektów.

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

Moja koncepcja polega na tym, że należy przeciągnąć zmienne sesji do zmiennych lokalnych, a następnie odpowiednio je obsługiwać. Zawsze zakładaj, że zmienne sesji mogą mieć wartość null i nigdy nie rzutuj ich na typ, który nie dopuszcza wartości null.

Jeśli potrzebujesz zmiennej wpisanej bez wartości null, możesz użyć TryParse, aby to uzyskać.

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

Moim zdaniem najłatwiejszym sposobem na zrobienie tego, który jest jasny i łatwy do odczytania, jest:

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

Może nie jest to najbardziej wydajna metoda, ponieważ rzutuje domyślną wartość ciągu nawet w przypadku domyślnej (rzutowanie łańcucha jako ciągu), ale jeśli uczynisz to standardową praktyką kodowania, okaże się, że działa ona dla wszystkich typów danych, i jest łatwo czytelny.

Na przykład (całkowicie fałszywy przykład, ale pokazuje o co chodzi):

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

Podoba mi się opcja Generics, ale wydaje mi się, że to przesada, chyba że spodziewasz się, że będzie to potrzebne w każdym miejscu. Metodę rozszerzeń można zmodyfikować, aby specjalnie rozszerzyć obiekt Session, tak aby miała „bezpieczną” opcję get, taką jak Session.StringIfNull („SessionVar”) i Session [„SessionVar”] = „myval”; Łamie prostotę dostępu do zmiennej poprzez Session ["SessionVar"], ale jest to czysty kod i nadal pozwala na sprawdzanie wartości null lub string, jeśli jest to potrzebne.


1

Sprawdzanie niczego / wartości Null jest sposobem na zrobienie tego.

Radzenie sobie z typami obiektów nie jest właściwą drogą. Zadeklaruj ścisły typ i spróbuj rzutować obiekt na właściwy typ. (I użyj podpowiedzi rzutowej lub Konwertuj)

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

Przepraszam za wszelkie naruszenia składni, jestem codziennym VB'erem


1

Zazwyczaj tworzę SessionProxy z silnie wpisanymi właściwościami dla elementów w sesji. Kod, który uzyskuje dostęp do tych właściwości, sprawdza wartość null i wykonuje rzutowanie na odpowiedni typ. Fajną rzeczą w tym jest to, że wszystkie moje elementy związane z sesjami są przechowywane w jednym miejscu. Nie muszę się martwić używaniem różnych kluczy w różnych częściach kodu (i zastanawiam się, dlaczego to nie działa). A dzięki wstrzykiwaniu zależności i mockowaniu mogę w pełni przetestować to za pomocą testów jednostkowych. Jeśli przestrzega zasad DRY, a także pozwala mi zdefiniować rozsądne wartości domyślne.

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

Lubię też zawijać zmienne sesji we właściwościach. Setery są tutaj trywialne, ale lubię pisać metody get, więc mają tylko jeden punkt wyjścia. Aby to zrobić, zwykle sprawdzam wartość null i ustawiam ją na wartość domyślną przed zwróceniem wartości zmiennej sesji. Coś takiego:

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

}


1

Ta metoda również nie zakłada, że ​​obiekt w zmiennej Session jest łańcuchem

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

Zasadniczo zastępuje zmienną null pustym ciągiem przed przekształceniem jej w łańcuch, ponieważ ToStringjest częścią Objectklasy


0

Jeśli wiesz, że jest to ciąg, możesz użyć funkcji String.IsEmptyOrNull ().


0

Czy używasz platformy .NET 3.5? Utwórz metodę rozszerzenia 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
Można to zapisać: public static bool Is (wejście tego obiektu) {return input == null; }
James Curran,

Należy uważać na metody rozszerzania.
Chris Pietschmann,

1
Dlaczego powinienem uważać na metody rozszerzenia?
Michael Kniskern

dlaczego po prostu nie używasz x == null lub x! = null?
Benoit

0

w ten sposób można sprawdzić, czy taki klucz jest dostępny

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.