¿Cuál es la mejor manera de determinar que una variable de sesión es nula o está vacía en C #?


79

¿Cuál es la mejor manera de verificar la existencia de una variable de sesión en ASP.NET C #?

Me gusta usar String.IsNullOrEmpty()trabajos para cadenas y me preguntaba si había un método similar para Session. Actualmente, la única forma que conozco es:

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

Respuestas:


114

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

La capa central. Esto está 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 pesado para los captadores / definidores 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 también agrego Getters / Setters para tipos específicos, especialmente cadenas, ya que a menudo prefiero trabajar con string.Empty en lugar de null para las variables presentadas a los usuarios.

p.ej:

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í...

Luego creo envoltorios para abstraer eso y llevarlo al modelo de aplicación. Por ejemplo, si tenemos datos del cliente:

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

¿Captas la idea cierto? :)

NOTA: Solo tuve un pensamiento al agregar un comentario a la respuesta aceptada. Asegúrese siempre de que los objetos sean serializables cuando los almacene en Session cuando utilice un servidor de estado. Puede ser muy fácil intentar guardar un objeto usando los genéricos cuando está en una granja web y se dispara. Implemento en una granja web en el trabajo, así que agregué controles a mi código en la capa central para ver si el objeto es serializable, otro beneficio de encapsular los captadores y configuradores de sesión :)


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

¿Cómo puedo manejar las excepciones si "lanzar una nueva ApplicationException (" Sin contexto Http, sin sesión para obtener! ");" ¿Se ejecuta ?, me confunden las propiedades implementadas automáticamente, en qué parte del código podría obtener la excepción cuando ocurre.
Marztres

Buen enfoque. Tengo problemas para implementar esto en una biblioteca de clases de C #. No puedo resolver las referencias a HttpSessionState/ HttpContext. ¿Tuvo que instalar la biblioteca MVC en la DLL para importar los espacios de nombres adecuados?
biscuit

18

Así es como lo haces. Sin embargo, hay una sintaxis más corta que puede utilizar.

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

Esto significa que si las variables de sesión son nulas, establezca sSession en "establecer esto"


1
no puedes hacer esto ... Session ["variable"] es un Object y el compilador lo convertirá a String porque sSession es una String, si la Session ["variable"] no existe, lanza una excepción !
balexandre

Estás absolutamente en lo correcto. Actualicé el código para lanzar la cadena si Session no es nula.
Ely

14

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

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

entonces puedes tratarlo como una cuerda.

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

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

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

1
Vea mi respuesta, el uso de genéricos habilita la seguridad de tipos al almacenar otros objetos.
Rob Cooper

Disculpe, ¿la parte 'Sesión ("' es correcta? Recibo errores.
Jesús Zamora

Estaría en VB. :) cambiado a corchetes.
Greg Ogle

8

La notación 'como' en c # 3.0 es muy limpia. Dado que todas las variables de sesión son objetos que aceptan valores NULL, esto le permite tomar el valor y ponerlo en su propia variable escrita sin preocuparse de lanzar una excepción. La mayoría de los objetos se pueden manejar 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 asuma que sus variables de sesión podrían ser nulas y nunca las convierta en un tipo que no acepta valores NULL.

Si necesita una variable de tipo no anulable, 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;
}

2

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

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

Puede que no sea el método más eficiente, ya que arroja el valor de cadena predeterminado incluso en el caso del valor predeterminado (convertir 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 de fácil lectura.

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 Genéricos, pero parece una exageración a menos que espere necesitar esto por todas partes. El método de extensiones podría modificarse para extender específicamente el objeto Session de modo 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 lo necesita.


1

Verificar nada / Nulo es la forma de hacerlo.

Tratar con tipos de objetos no es el camino a seguir. Declare un tipo estricto e intente convertir el objeto al tipo correcto. (Y usa la sugerencia de transmisión 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;
 }

Perdón por las violaciones de sintaxis, soy un VB'er diario


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 los elementos relacionados con mi sesión se guardan en un solo lugar. No tengo que preocuparme por usar diferentes claves en diferentes partes del código (y preguntarme por qué no funciona). Y con la inyección de dependencia y la 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; }
    }
}

1

También me gusta envolver variables de sesión en propiedades. Los establecedores aquí son triviales, pero me gusta escribir los métodos get para que solo tengan un punto de salida. Para hacer eso, generalmente verifico si hay 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; }
}

}


1

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

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

Entonces, básicamente reemplaza la variable nula con una cadena vacía antes de convertirla en una cadena, ya que ToStringes parte de la Objectclase


0

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


0

¿Está utilizando .NET 3.5? Cree un método de extensión 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
Eso podría escribirse: public static bool Is (entrada de este objeto) {return input == null; }
James Curran

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

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

¿Por qué no usas simplemente x == nulo o x! = nulo?
Benoit

0

de esta forma se puede comprobar si dicha clave está disponible

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.