JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

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

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!

José Manuel Alarcón José Manuel Alarcón
Fundador y director de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (9) -

Excelente artículo ¡¡¡ Nunca está de más aparender buenas prácticas.
Gracias

Responder

¿Por qué dices que "es mejor usar poco" las vbles. de sesión?
Hay muchas aplicaciones en las que son necesarias, por no decir imprescindibles ¿Existe alguna alternativa equivalente?

Responder

Spain José Manuel Alarcón

Hola:

Las variables de sesión tienen multitud de inconvenientes si no se usan con cuidado. Por ejemplo a bote pronto se me ocurren:

· Su gestión poco cuidadosa puede hacer que queden establecidas inadvertidamente y luego provocan efectos "extraños".
· Si no las gestionas de manera similar a como indico en el post son difíciles de mantener y es fácil confundirse de nombre y meter la pata.
· Como toda variable genérica, no tipada, son fuente de posibles problemas de uso, valore sno deseados por conversiones de tipo automáticas, etc... (pregúntale a los programadores de JavaScript sino).
· Consumen memoria y mal usadas pueden tener impacto en la escalabilidad.
· En entornos Web-garden o Web-Farm son difíciles de mantener y obligan a mantener afinidad en las peticiones. En estos casos la configuración es delicada, debes usar almacenamiento centralizado en memoria (más lento y menos eficiente) o una base de datos centralizada. También existen servidores especializados para hacer caché/almacenamiento distribuido que podrías utilizar, pero complican.

Seguro que si me estrujo un poco más más salen más inconvenientes :-)

Saludos,

Responder

Costa Rica Cara de Barro

esto es un copia barat : www.jasoft.org/.../...s-de-sesion-como-un-PRO.aspx, digo copia por que fue COPIADO dos dias despues !!!!  

Responder

Spain José M. Alarcón

Hola Cara de Barro:

No entiendo lo que me dices: ¿me estás diciendo que me copié a mi mismo?...

Aclárate un poquito ;-)

Responder

Costa Rica Cara de Barro

disculpa el que te copio fue : geeks.ms/.../...les-de-sesi-243-n-como-un-pro.aspx, mil disculpas

Responder

Spain José M. Alarcón

Si te fijas bien, ese post es mío también. Hago cross-posting a geeks.ms siempre un par de días después de publicar aquí. Ese blog es una copia literal del mío ¡porque la hago yo! Fíjate bien en quién lo firma y en que además pongo un enlace al original en todos los posts de Geeks. Lo hago porque geeks es una gran comunicada que además han montado amigos míos y me pidieron estar allí ya hace muchos años.

Asi que en conclusion: no es que lo copie es que hago cross-posting.

En cualquier caso gracias por avisar.

Saludos,

Responder

Jesus Herrera

Hola que tal .. tendras de casualidad alternativas para el uso de Sessiones y ejemeplos ?
Gracias !

Responder

by Jose M. Alarcon

Hola:

Si no quieres usar cookies de sesión lo tienes fácil. Este simple ajuste en web.config hará que se usen identificadores de sesión en la URL y así no dependerás de cookies:

<sessionState cookieless="UseUri" />

En general, en cualquier caso, no es buena idea depender demasiado de valores almacenados en sesión ya que complican el mantenimiento del código y además pueden limitar la escalabilidad.

Saludos.

Responder

Agregar comentario