Wie kann am besten festgestellt werden, dass eine Sitzungsvariable in C # null oder leer ist?


79

Wie kann am besten überprüft werden, ob in ASP.NET C # eine Sitzungsvariable vorhanden ist?

Ich verwende gerne String.IsNullOrEmpty()Werke für Streicher und frage mich, ob es eine ähnliche Methode für gibt Session. Derzeit ist mir nur Folgendes bekannt:

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

Antworten:


114

Um dem zu folgen, was andere gesagt haben. Ich neige dazu, zwei Schichten zu haben:

Die Kernschicht. Dies befindet sich in einer DLL, die fast allen Web-App-Projekten hinzugefügt wird . In dieser habe ich eine SessionVars-Klasse, die das Grunzen für Session State Getter / Setter erledigt. Es enthält Code wie den folgenden:

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

Beachten Sie die Generika zum Abrufen eines beliebigen Typs.

Ich füge dann auch Getters / Setter für bestimmte Typen hinzu, insbesondere für Zeichenfolgen, da ich es oft vorziehe, mit Zeichenfolgen zu arbeiten. Leere statt Null für Variablen, die Benutzern angezeigt werden.

z.B:

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

Und so weiter...

Ich erstelle dann Wrapper, um das zu abstrahieren und es auf das Anwendungsmodell zu bringen. Zum Beispiel, wenn wir Kundendaten haben:

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

Verstehst du die Idee richtig? :) :)

HINWEIS: Ich hatte gerade einen Gedanken, als ich der akzeptierten Antwort einen Kommentar hinzufügte. Stellen Sie immer sicher, dass Objekte serialisierbar sind, wenn Sie sie in Session speichern, wenn Sie einen Statusserver verwenden. Es kann allzu einfach sein, ein Objekt mithilfe der Generika zu speichern, wenn es sich in einer Webfarm befindet, und es boomt. Ich stelle auf einer Webfarm bei der Arbeit bereit und füge meinem Code in der Kernebene Überprüfungen hinzu, um festzustellen, ob das Objekt serialisierbar ist. Ein weiterer Vorteil der Kapselung der Session Getter und Setter :)


Toller Ansatz! Ich habe lange Zeit etwas Ähnliches verwendet, aber keine Generika eingebaut. Dies vermeidet so viele Probleme mit verschiedenen Entwicklern, die ähnliche Sitzungsvariablen erstellen.
DOK

Wie kann ich Ausnahmen behandeln, wenn "Neue ApplicationException auslösen (" Kein HTTP-Kontext, keine Sitzung zum Abrufen! ");" wird ausgeführt? Ich bin verwirrt über die automatisch implementierten Eigenschaften. In welchem ​​Teil des Codes könnte ich die Ausnahme bekommen, wenn sie auftritt.
Marztres

Netter Ansatz. Ich habe Probleme, dies in einer C # -Klassenbibliothek zu implementieren. Ich kann Verweise auf HttpSessionState/ nicht auflösen HttpContext. Mussten Sie die MVC-Bibliothek in der DLL installieren, um die richtigen Namespaces zu importieren?
Seebiscuit

18

So machst du es so ziemlich. Es gibt jedoch eine kürzere Syntax, die Sie verwenden können.

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

Wenn die Sitzungsvariablen null sind, setzen Sie sSession auf "set this".


1
Sie können dies nicht tun ... Session ["Variable"] ist ein Objekt und der Compiler konvertiert es dann in einen String, da sSession ein String ist. Wenn die Session ["Variable"] nicht existiert, wird eine Ausnahme ausgelöst !
Balexandre

Sie sind absolut richtig. Ich habe den Code aktualisiert, um die Zeichenfolge umzuwandeln, wenn Session nicht null ist.
Ely

14

Es kann die Dinge eleganter machen, es in eine Eigenschaft zu wickeln.

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

dann können Sie es als Zeichenfolge behandeln.

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

Dies ist, was ich mache, macht es viel einfacher, auf Sitzungsvariablen in einer App zuzugreifen. Ich neige dazu, Klassen für die Daten und statische Eigenschaften zu erstellen, die die gesamte Null-Check-Grunzarbeit erledigen.
Rob Cooper

Was ist, wenn Sie ein Objekt in der Sitzung speichern und nicht nur eine Zeichenfolge?
Aaron Palmer

1
Siehe meine Antwort, die Verwendung von Generika ermöglicht die Typensicherheit beim Speichern anderer Objekte.
Rob Cooper

Entschuldigung, ist der Teil 'Sitzung ("' korrekt? Ich erhalte Fehler.
Jesus Zamora

Es wäre in VB. :) in eckige Klammern geändert.
Greg Ogle

8

Die 'as'-Notation in c # 3.0 ist sehr sauber. Da alle Sitzungsvariablen nullfähige Objekte sind, können Sie den Wert abrufen und in Ihre eigene typisierte Variable einfügen, ohne eine Ausnahme auslösen zu müssen. Die meisten Objekte können auf diese Weise behandelt werden.

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

Mein Konzept ist, dass Sie Ihre Sitzungsvariablen in lokale Variablen ziehen und sie dann entsprechend behandeln sollten. Nehmen Sie immer an, dass Ihre Sitzungsvariablen null sein könnten, und wandeln Sie sie niemals in einen nicht nullbaren Typ um.

Wenn Sie eine nicht nullfähige typisierte Variable benötigen, können Sie TryParse verwenden, um diese zu erhalten.

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

Meiner Meinung nach ist der einfachste Weg, dies klar und leicht zu lesen, folgender:

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

Es ist möglicherweise nicht die effizienteste Methode, da der Standardzeichenfolgenwert auch im Fall der Standardeinstellung (Umwandlung einer Zeichenfolge als Zeichenfolge) umgewandelt wird. Wenn Sie ihn jedoch zu einer Standardcodierungspraxis machen, funktioniert er für alle Datentypen. und ist leicht lesbar.

Zum Beispiel (ein völlig falsches Beispiel, aber es zeigt den Punkt):

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

Ich mag die Generika-Option, aber es scheint übertrieben, es sei denn, Sie erwarten, dass Sie dies überall brauchen. Die Erweiterungsmethode kann geändert werden, um das Sitzungsobjekt spezifisch zu erweitern, sodass es eine "sichere" get-Option wie Session.StringIfNull ("SessionVar") und Session ["SessionVar"] = "myval" hat. Es bricht die Einfachheit des Zugriffs auf die Variable über Sitzung ["SessionVar"], ist jedoch sauberer Code und ermöglicht weiterhin die Überprüfung, ob null oder eine Zeichenfolge, falls erforderlich.


1

Auf nichts / Null prüfen ist der Weg, dies zu tun.

Der Umgang mit Objekttypen ist nicht der richtige Weg. Deklarieren Sie einen strengen Typ und versuchen Sie, das Objekt in den richtigen Typ umzuwandeln. (Und Cast Cast oder Convert verwenden)

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

Entschuldigung für Verstöße gegen die Syntax, ich bin ein täglicher VB'er


1

Normalerweise erstelle ich SessionProxy mit stark typisierten Eigenschaften für Elemente in der Sitzung. Der Code, der auf diese Eigenschaften zugreift, prüft auf Nichtigkeit und führt das Casting auf den richtigen Typ durch. Das Schöne daran ist, dass alle meine sitzungsbezogenen Elemente an einem Ort aufbewahrt werden. Ich muss mich nicht darum kümmern, verschiedene Schlüssel in verschiedenen Teilen des Codes zu verwenden (und mich zu fragen, warum es nicht funktioniert). Und mit Abhängigkeitsinjektion und Verspottung kann ich es mit Unit-Tests vollständig testen. Wenn folgt DRY Prinzipien und lässt mich auch vernünftige Standardeinstellungen definieren.

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

Ich mag es auch, Sitzungsvariablen in Eigenschaften zu verpacken. Die Setter hier sind trivial, aber ich schreibe gerne die get-Methoden, damit sie nur einen Austrittspunkt haben. Dazu suche ich normalerweise nach null und setze es auf einen Standardwert, bevor ich den Wert der Sitzungsvariablen zurückgebe. Etwas wie das:

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

}}


1

Diese Methode setzt auch nicht voraus, dass das Objekt in der Sitzungsvariablen eine Zeichenfolge ist

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

Ersetzt also im Grunde die Nullvariable durch eine leere Zeichenfolge, bevor sie in eine Zeichenfolge konvertiert wird, da sie ToStringTeil der ObjectKlasse ist


0

Wenn Sie wissen, dass es sich um eine Zeichenfolge handelt, können Sie die Funktion String.IsEmptyOrNull () verwenden.


0

Verwenden Sie .NET 3.5? Erstellen Sie eine IsNull-Erweiterungsmethode:

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
Das könnte geschrieben werden: public static bool Is (diese Objekteingabe) {return input == null; }
James Curran

Sie sollten mit Erweiterungsmethoden vorsichtig sein.
Chris Pietschmann

1
Warum sollte ich mit Erweiterungsmethoden vorsichtig sein?
Michael Kniskern

Warum benutzt du nicht einfach x == null oder x! = null?
Benoit

0

Auf diese Weise kann geprüft werden, ob ein solcher Schlüssel verfügbar ist

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.