Cómo gestionar variables de sesión como un PRO

Post original en JASoft.org: http://www.jasoft.org/Blog/post/Como-gestionar-variables-de-sesion-como-un-PRO.aspx

httpA la hora de trabajar con sesiones en C#, el mayor problema es que, al contrario que en VB, no se facilita el manejo directo de los valores como si fueran propiedades del objeto Session ni se transforman al tipo correcto para hacer operaciones como Session("Contador")++ y similares. Además, adicionalmente, hay que comprobar que las variables existan antes de poder hacer todas estas operaciones.

Por ejemplo, si queremos trabajar con una cadena de texto en sesión y poder asignarle un valor, se trata de algo tan sencillo como lo es en VB ya que sólo debes asignarla directamente, así:

   1: Session["TextoAGuardar"] = "Este es el texto que quiero almacenar";

Sin embargo si lo necesitamos es realizar una operación matemática es un poco más lioso ya que deberemos comprobar primero que la variable existe y contiene un valor, y ademas convertirla desde "object" que es lo que devuelve por defecto una variable de sesión, al tipo correcto, cosa que VB hace automáticamente. Por ejemplo:

   1: if (Session["Contador"] != null) 
   2:     Session["Contador"] = ((int)Session["Contador"])+1;

Lo que ocurre es que casi ningún programador profesional trabaja de este modo.

Lo que se suele hacer es crear una clase auxiliar que haga todos los accesos a las variables de sesión a través de sus métodos o de sus propiedades.

En esta clase auxiliar por un lado definimos constantes que representan los identificadores de las variables de sesión. De este modo si luego decidimos cambiarlas lo hacemos en un solo sitio y además eliminamos la posibilidad de equivocarnos al escribirlas donde usemos la sesión. Por ejemplo:

   1: public class SessionHelper
   2: {
   3:     //Constantes de variables de sesión
   4:     public const string CONTADORVAR = "Contador";
   5:     public const string TEXTOVAR = "Texto";
   6: }

Además ahora le añadimos un par de métodos genéricos que nos faciliten leer y escribir variables en la sesión a, por ejemplo:

   1: public static T Lee<T>(string variable)
   2: {
   3:     object valor = HttpContext.Current.Session[variable];
   4:     if (valor == null)
   5:         return default(T);
   6:     else
   7:         return ((T)valor);
   8: }
   9:  
  10: public static void Escribe(string variable, object valor)
  11: {
  12:     HttpContext.Current.Session[variable] = valor;
  13: }

De este modo es muy sencillo leer cualquier variable, simplemente escribiendo por ejemplo:

   1: Lee<int>(CONTADORVAR);

que lee la variable "Contador" o escribir en ella con esta línea:

   1: Escribe(CONTADORVAR, value)

Pero todavía es más útil y con más posibilidades crear propiedades en nuestra clase auxiliar, de modo que podamos leer y escribir en las correspondientes variables de sesión con sólo indicar algo así:

   1: SessionHelper.Contador = 0;
   2: int miValorEnSesion = SessionHelper.Contador;

Para conseguir esto sólo debemos definir una simple propiedad de la siguiente manera:

   1: public static int Contador { 
   2:         get
   3:         {
   4:             return Lee<int>(CONTADORVAR);
   5:         }
   6:         set
   7:         {
   8:             Escribe(CONTADORVAR, value);
   9:         } 
  10: }

Con esto simplificamos al máximo el acceso a las variables, eliminamos errores, les podemos añadir cualqueir tipo de validación o trasformación previa a leerlas o escribirlas y además funcionarán también expresiones de este tipo:

   1: SessionHelper.Contador++;

para por ejemplo incrementar el valor de la variable de sesión en 1.

Todo lo explicado es, por supuesto, válido también para VB pero se le saca más partido desde C#. Las variables de sesión son útiles pero restan escalabilidad a las aplicaciones y son propensas a producir errores si no las utilizamos correctamente, así que es mejor usarlas poco.

El código completo para la nuestra clase auxiliar que incluye acceso a dos variables de sesión (una entera y la otra de texto) quedaría de la siguiente manera:

 

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5:  
   6: public class SessionHelper
   7: {
   8:     //Constantes de variables de sesión
   9:     public const string CONTADORVAR = "Contador";
  10:     public const string TEXTOVAR = "Texto";
  11:     
  12:     public static T Lee<T>(string variable)
  13:     {
  14:         object valor = HttpContext.Current.Session[variable];
  15:         if (valor == null)
  16:             return default(T);
  17:         else
  18:             return ((T)valor);
  19:     }
  20:  
  21:     public static void Escribe(string variable, object valor)
  22:     {
  23:         HttpContext.Current.Session[variable] = valor;
  24:     }
  25:  
  26:     public static int Contador { 
  27:         get
  28:         {
  29:             return Lee<int>(CONTADORVAR);
  30:         }
  31:         set
  32:         {
  33:             Escribe(CONTADORVAR, value);
  34:         } 
  35:     }
  36:  
  37:     public static string Texto
  38:     {
  39:         get
  40:         {
  41:             return Lee<string>(TEXTOVAR);
  42:         }
  43:         set
  44:         {
  45:             Escribe(TEXTOVAR, value);
  46:         }
  47:     }
  48:  
  49: }

¡Espero que te sea útil!

Archivado en:
Comparte este post:

Comentarios

# Javier Torrecilla said:

Gran post Jose!

Thursday, July 26, 2012 3:43 PM
# José M. Alarcón Aguín said:

Gracias! :-)

Thursday, July 26, 2012 4:59 PM
# Rodrigo Corral said:

Buen consejo... parece muy evidente pero hay gente que lo ignora.

Yo lo mejoraria un poco.... poniendome purista: las constantes en C# deben ser PascalCase :)

Un saludo titán.

Thursday, July 26, 2012 10:17 PM
# José M. Alarcón Aguín said:

Hola Rodrigo,

Ya sabes que soy de la vieja escuela y me resisto a cambiar algunas costumbres de la buena y prestigiosa escuela húngara ;-)

Para mi las constantes siempre serán en mayúsculas. Realmente me parece que ayuda bastante identificarlas así.

Además en mi opinión lo único importante es tener una notación y seguirla siempre y ser consistente, sea cual sea ésta.

Gracias por comentar.

Ah, y ¡feliz cumpleaños! ;-)

Friday, July 27, 2012 7:56 AM