2008-10-24 15 views
70

¿Cuál es la mejor manera de verificar la existencia de una variable de sesión en ASP.NET C#?¿Cuál es la mejor manera de determinar si una variable de sesión es nula o está vacía en C#?

Me gusta usar String.IsNullOrEmpty funciona para cadenas y me pregunto si existe un método similar para Session. Actualmente, la única forma que conozco es:

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

Respuesta

106

Para seguir con lo que otros han dicho. Tiendo a tener dos capas:

La capa del núcleo. Esto se encuentra dentro de una DLL que se agrega a casi todos los proyectos de aplicaciones web. En esto tengo una clase SessionVars que hace el trabajo ronco para getters/setters de estado de sesión. Contiene código como el siguiente:

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

Tenga en cuenta los genéricos para obtener cualquier tipo.

Luego agrego Getters/Setters para tipos específicos, especialmente cadenas, ya que a menudo prefiero trabajar con cadenas. Vacío en lugar de nulo para las variables presentadas a los usuarios.

e.g:

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

Y así sucesivamente ...

entonces crear contenedores para abstraer eso y llevarlo hasta el modelo de aplicación. Por ejemplo, si tenemos los datos del cliente:

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

Usted consigue la idea correcta? :)

NOTA: Apenas tuve un pensamiento al agregar un comentario a la respuesta aceptada. Siempre asegúrese de que los objetos sean serializables cuando los almacena en Sesión cuando usa un servidor de estado. Puede ser muy fácil intentar y guardar un objeto usando los genéricos cuando está en la granja de servidores web y se dispara. Despliegue en una granja de servidores web en el trabajo, así que agregué cheques a mi código en la capa central para ver si el objeto es serializable. Otra ventaja de encapsular Session Getters y Setters :)

+1

Gracias por proporcionar respuestas completas. ¡Muy bueno! –

+0

No hay problema, HTH:) –

+0

Gran enfoque! He estado usando algo similar durante mucho tiempo, pero no he incorporado genéricos. Esto evita tantos problemas con diferentes desarrolladores que crean variables de sesión similares. – DOK

17

Así es más o menos cómo lo haces. Sin embargo, hay una sintaxis más corta que puede usar.

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

Esto es decir, si las variables de sesión es nula, establecer sSession a "establecer este"

+1

no puede hacer esto ... Session ["variable"] es un Objeto y el compilador lo convertirá en una Cadena porque sSession es una Cadena, si la Sesión ["variable"] no existe, arroja una excepción! – balexandre

+0

Tiene toda la razón. Actualicé el código para lanzar la cadena si Session no es nulo. – Ely

1

Comprobación de nada/Null es la manera de hacerlo.

Tratar con tipos de objetos no es el camino a seguir. Declare un tipo estricto y trate de convertir el objeto al tipo correcto. (Y el uso de pista yeso o Convertir)

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

Lo siento por cualquier violaciónes de sintaxis, soy un VB'er diaria

0

¿Está utilizando .NET 3.5? Crear un método de extensión EsNulo:

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

Que podría escribirse: public static bool Is (esta entrada de objeto) { return input == null; } –

+0

Debe tener cuidado con los métodos de extensión. –

+1

¿Por qué debería tener cuidado con los métodos de extensión? –

0

Si usted sabe que es una cadena, puede utilizar la función String.IsEmptyOrNull().

14

Puede hacer las cosas más elegantes para envolverlo en una propiedad.

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

luego puede tratarlo como una cadena.

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

Esto es lo que hago, hace que sea mucho más fácil acceder a los vars de sesión en una aplicación. Tiendo a hacer clases para los datos, y propiedades estáticas que hacen que todo el trabajo de verificación nulo funcione. –

+0

¿Qué sucede si está almacenando un objeto en la sesión y no solo una cadena? –

+1

Vea mi respuesta, el uso de genéricos permite la seguridad de tipo cuando se almacenan otros objetos. –

1

Normalmente, creo SessionProxy con propiedades fuertemente tipadas para los elementos de la sesión. El código que accede a estas propiedades comprueba la nulidad y realiza la conversión al tipo adecuado. Lo bueno de esto es que todos mis artículos relacionados con la sesión se mantienen en un solo lugar. No tengo que preocuparme por usar claves diferentes en diferentes partes del código (y me pregunto por qué no funciona). Y con inyección de dependencia y burla puedo probarlo completamente con pruebas unitarias. Si sigue los principios DRY y también me permite definir valores predeterminados razonables.

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

La notación 'como' en C# 3.0 es muy limpio. Como todas las variables de sesión son objetos que aceptan nulos, esto le permite tomar el valor y ponerlo en su propia variable tipeada sin preocuparse de lanzar una excepción. La mayoría de los objetos pueden manejarse de esta manera.

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

Mi concepto es que debe extraer sus variables de Sesión en variables locales y luego manejarlas adecuadamente. Siempre suponga que sus variables de Sesión podrían ser nulas y nunca convertirlas en un tipo que no admite nulos.

Si necesita una variable tipeada que no admite nulos, puede usar TryParse para obtenerla.

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

También me gusta ajustar las variables de sesión en las propiedades. Los setters aquí son triviales, pero me gusta escribir los métodos get para que tengan solo un punto de salida. Para hacer eso, generalmente comprobo nulo y lo configuro en un valor predeterminado antes de devolver el valor de la variable de sesión. Algo como esto:

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

}

2

En mi opinión, la manera más fácil de hacer esto que es clara y fácil de leer es:

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

tal vez no sea el más eficiente método, ya que arroja el valor de cadena predeterminado incluso en el caso del valor predeterminado (conversión de una cadena como cadena), pero si lo convierte en una práctica de codificación estándar, encontrará que funciona para todos los tipos de datos y es fácil de leer.

Por ejemplo (un ejemplo totalmente falso, pero muestra el punto):

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

me gusta la opción de los genéricos, pero parece un exceso a menos que vaya a necesitar esto por todo el lugar. El método de extensiones podría modificarse para extender específicamente el objeto Session de manera que tenga una opción de obtención "segura" como Session.StringIfNull ("SessionVar") y Session ["SessionVar"] = "myval"; Rompe la simplicidad de acceder a la variable a través de Session ["SessionVar"], pero es un código limpio, y aún permite validar si es nulo o si es una cadena si la necesita.

1

Este método también no asume que el objeto en la variable de sesión es una cadena

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

Así que básicamente reemplaza la variable nula con una cadena vacía antes de convertirlo en una cadena desde ToString es parte de la Object clase

Cuestiones relacionadas