Hacer caché sólo durante la petición actual

Siempre que se habla de la caché suele hacerse refiriéndose a la caché persistente que todos estamos acostumbrados a conocer y usar, bien la caché de salida de las páginas o bien la caché programática usando la clase System.Web.Caching.Cache.


Sin embargo hay ocasiones en las que probablemente nos interesaría más hacer una caché mucho menos persistente. Algo que nos dure lo justo para el propósito de un momento determinado y luego no nos tengamos que preocupar siquiera de deshacernos de ella. En concreto me estoy refiriendo a la caché de contexto o caché de una sola petición.


Imaginemos el caso: en una petición usamos un manejador propio para interceptarla y hacer algo antes de ser procesada la página o bien obtenemos alguna información más o menos costosa durante un evento de global.asax (en BeginRequest o durante la autenticación de la petición). El caso es que esa información la necesitamos usar de nuevo varias veces durante lo que dura la petición actual: en otros módulos o en diversas partes de la página.


Si sólo debemos reutilizar la información en la propia página es muy fácil pues sólo debemos almacenarla en un miembro privado común de la clase que representa a la página y ya está. Pero si tenemos que conservar una serie de valores entre diferentes partes de la misma petición o compartirlos con clases de las que hacemos uso en la página, entonces la cosa no es tan directa.


La pregunta es entonces: ¿qué tenemos en común entre todas las partes (manejadores varios, módulos y nuestra página)? Algo que siempre esté presente… El contexto de la llamada, representado por la clase HttpContext.


A este objeto podemos acceder mediante la propiedad Context de la página actual o, en cualquier lugar del código que esté siendo usado desde una petición HTTP mediante la propiedad Current del propio objeto Httpcontext, así:



HttpContext contexto = HttpContext.Current;


Esta clase tiene una colección de elementos que podemos usar para almacenar con claves los valores que queramos guardar entre partes de esa petición, es decir, mientras dure el contexto. Para ello sólo tenemos que escribir y leer la colección Items que también es la colección por defecto:



HttpContext contexto = HttpContext.Current;
contexto.Items(«MiDato») = «lo que sea»;
string dato = contexto(«MiDato»).ToString();


Con esto podemos conservar la información mientras dure la llamada. Cuando ésta termina el objeto HttpContext se destruye (o se marca para que lo recoja el recolector de basura si queremos hablar con propiedad, antes de que «alguien» (y no miro a nadie) me venga a apuntillar) y la información desaparece, pero hemos tenido una caché de información en la que almacenar datos importantes mientras duraba toda la llamada.


En un siguiente post voy a comentar cómo podemos hacer una caché que valga sólo para un usuario y que nos dure automáticamente mientras el usuario esté utilizando la página actual y no otra. Es simple pero muy interesante. Hasta entonces.

Sin categoría

5 thoughts on “Hacer caché sólo durante la petición actual

  1. Hola Jose Manuel

    Estaba haciendo uso del HttpContext tal como lo comentas para guardar un arreglo de objetos el cual lo estaré usando durante la sesión. Sin embargo, en cuanto se da el reload de la página, este arreglo desaparece de la colección «Items» del contexto actual.

    Sabes como se puede remediar esto?

    Gracias

  2. Hola Mario:

    Tal y como explico en el post el contenido del contesto sólo dura mientras dure la llamada actual. Si recargas la página se trata de una llamada distinta.

    El contexto es útil cuando debes averiguar u obtener datos más o menos costosos en algún punto de la llamada (por ejemplo durante el evento BeginRequest de Global.asax) y reutilizarlos despues en diferentes módulos y en la página.

    Por ejemplo imagina que implementas un sistema que permite elegir la Master Page a utilizar para cada usuario. En el evento BeginRequest averiguas cual es la MP que vas a usar en la página actual (por ejemplo viendo en la BD o en una cookie la que ha escogido el usuario) y luego en un manejador posterior que has creado anotas en un log la llamada y la MP usada y además en la página, en el evento PreLoad, cambias dicha MP para que se visualice correctamente la página.

    Si guardas en el contexto el valor sólo lo tienes que recuperar una vez aunque lo usues en divesos sitios.

    Puedes ver un ejemplo muy bueno de uso si consultas el código del proyecto Open Source DotNetNuke (http://www.dotnetnuke.com/) que hace uso intensivo de esta caratcerística para generar dinámicamente muchas partes de cada página del portal.

    Saludos

    JM.

  3. Muchas gracias por tu ayuda.

    Si tienes alguna idea de como mantener los datos a pesar de que se recargue la pagina, agradecería mucho tus comentarios.

    Hasta luego y gracias de nuevo.

  4. Que tal interesante pero pregunta por ejemplo en mi situacion necesito un temporizador System.Timers.Timer para que verifique cada 20 minutos que es lo que dura la sesion que el usuario todavia este activo el problema es que en el evento de este timer la llamada a la proiedad HttpContext.current siempre viene vacia como podria conservar este ultimo para que funcione en el evento del timer

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *