miércoles, 3 de noviembre de 2010

¿Dónde guardar mis datos en ASP.NET?

A continuación y según mis propias palabras, enumero los métodos que tenemos en ASP.NET para guardar información entre páginas, sesiones y a nivel de aplicación.

  • Session
    • Ámbito de usuario.
    • No es compatible con web farm o web garden si estamos guardando la sesión “en proceso” (forma predeterminada). Si utilizamos un servidor de estado o guardamos la sesión en base de datos, entonces sí es compatible).
    • Ocupa memoria en el servidor (de nuevo siempre y cuando estemos guardándola “en proceso”), luego no es muy escalable ya que el gasto de memoria será de “Espacio*Nº de usuarios” y la memoria del servidor es un recurso valioso y finito.
    • Tiene un principio y un fin bien marcados (Session_OnStart y Session_OnEnd) con lo que se podría ir liberando recursos en el manejador Session_OnEnd.
      • Session_OnEnd sólo funciona para el modo predeterminado “en proceso”.
    • Cómo principio básico Jamás se debe guardar algo que sólo está disponible para el ciclo de vida de la página en Session o Application, para ello hay otros recursos más apropiados.
    • Cómo segundo principio básico, intentar evitar en la medida de lo posible el uso de la sesión. Tarde o temprano será un problema y mejor no tener que lidiar con él.
  • Application
    • Ámbito de aplicación (visible en todas las sesiones).
    • No es compatible con web farm o web garden.
    • Ocupa memoria en el servidor, mismas consideraciones que con Session.
    • Tiene un principio y un fin bien marcados (Application_OnStart y Application_OnEnd).
  • ViewState
  • Page.Items
    • Ámbito de ciclo de vida página (no incluye postback).
    • Sólo disponible para la página y sus componentes (controles de usuario por ejemplo).
  • HttpContext.Items
    • Ámbito de ciclo de vida página (no incluye postback).
    • Disponible para toda la petición (soporta por ejemplo Server.Transfer, controles de usuario, eventos HttpApplication, etc.).
  • Cache
    • Ámbito de aplicación (visible en todas las sesiones).
    • No es compatible con web farm o web garden.
    • Al igual que Application o Session, ocupa memoria en el servidor pero normalmente resulta una mejor opción porque si es necesario los elementos de cache serían descartados para restablecer memoria libre.
    • Dispone de diversas políticas de expiración e incluso dependencias con recursos externos.
  • Campos HIDDEN
    • Ámbito de página (incluyendo viajes de ida y vuelta – postback).
    • Ocupa ancho de red puesto que el dato viaja y se guarda en cliente.
    • Los datos que se quieran guardar tiene que poderse serializar.
    • Visible y fácilmente manipulable por el usuario, se podría comprometer la seguridad de nuestra aplicación.
    • Un valor por campo (a menos de serie y sin utilizar ningún tipo de tratamiento después con Split, etc.)
  • QueryString
    • Ámbito de página (incluyendo viajes de ida y vuelta – postback).
    • QueryString tiene un tamaño máximo según servidor y navegador.
    • Visible y fácilmente manipulable por el usuario.
    • Pequeñas cantidades de datos.
  • Cookies
    • Ámbito establecido por la cookie, normalmente de aplicación.
    • Se guarda en el cliente.
    • Fácilmente manipulable por el cliente.
    • Tiene un tamaño máximo por navegador.
    • Pequeñas cantidades de datos.
    • Pueden estar desactivadas por el usuario en su navegador.
  • Memcached
  • NCache

Un saludo!

2 comentarios:

  1. Ahora estoy teniendo problemas y los usuarios una vez logueados se "mezclan". Es decir, el usuario jmartinez abre la aplicación y de repente aparece como vruiz. Casualmente están conectados ambos.

    ¿Por qué me lo puede estar haciendo?

    Tengo una clase mySession dónde almaceno los datos del usuario y más parámetros únicos para el usuario.

    Ya no se por dónde seguir...

    ResponderEliminar
  2. Mooookie!
    A ver si puedo ayudarte.
    El servidor identifica la sesión del usuario a través de la cookie "ASP.NET_SessionId".
    Mira si tus usuarios tienen el mismo valor en esa cookie.
    Además, si tienes un enlace tipo "desconectar" llama al método Session.Abandon() que borra la cookie sin esperar a Session_OnEnd, y además cada vez que el usuario se conecte también puedes llamar a Session.Clear() para asegurarte que no hereda nada de una posible sesión anterior.
    También mira que suceda el evento Session_OnStart (con depuración en el fichero global.asax).
    Uff, sin ver el código no se me ocurre mucho más.
    Si el problema persiste lo vemos por correo o al Skype.
    De todas formas, con el paso del tiempo he aprendido a "odiar" la sesión y la "evito" siempre que puedo.
    Un saludo!

    ResponderEliminar