2011-02-04 14 views
5

Para un sitio web, quiero almacenar en caché las páginas SÓLO para usuarios que no están autenticados: los usuarios autenticados no reciben contenido en caché (ya que estarán actualizando y necesitan ver resultados correctos lejos).Almacenamiento de contenido en caché solo para usuarios no autenticados

sé cómo variar la memoria caché para cada usuario utilizando VaryByCustom: Link1 Link2

... pero no puedo encontrar la manera de desactivar el almacenamiento en caché en su totalidad para los usuarios autenticados.

¿Qué hacer?

Editar

El código de abajo tiene un problema si ya existe una versión en caché de la página de un usuario no autenticado. Básicamente, al usuario autenticado se le servirá la vista no autenticada de las cosas.

Sin embargo, este enlace de aquí tiene la solución que funciona: Link

+0

puede crear su atributo de caché personalizado que comprobar si se ha autenticado el usuario y después de hacer un poco de lógica (la caché o no la salida de caché). –

+0

Suena bien, RoBYCoNTe. Debe escribirlo como una respuesta para que la gente pueda votarlo. :) – Kjensen

Respuesta

3
+0

¡En realidad, el mío crearía una nueva versión para cada solicitud! Por lo tanto, el usuario autenticado nunca debería ver contenido en caché. Pero, de nuevo, es posible que tenga un nuevo problema, la contaminación del caché.Hmmm, déjame seguir sobre esto. Tal vez devolver el nulo de esto funcionaría. – Haacked

0

es posible que desee crear dos controladores, uno para los usuarios autenticados (donde no almacenar en caché), uno para los usuarios no autenticados (donde se hace una caché) . Luego puede refractar la lógica en los controladores a un "objeto de capa empresarial" común para mantener su código SECO y la unidad susceptible de prueba.

+0

Esa es una forma de hacerlo, pero debe haber una mejor manera. – Kjensen

2

Inspirándose en la Link1 informados, como fácil de código idea es que se puede modificar la impresión de los medios de neutralización GetVaryByCustomString de la siguiente manera:

public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
    if (arg == "IsLoggedIn") 
    { 
     if (context.Request.Cookies["anon"] != null) 
     { 
      if (context.Request.Cookies["anon"].Value == "false") 
      { 
       return "auth"; 
      } 
     } 
     return Guid.New().ToString(); 
    } 
    else 
    { 
     return base.GetVaryByCustomString(context, arg); 
    } 
} 

Esto no es realmente una respuesta técnicamente como la autenticado la salida del usuario aún se almacenará en caché, pero cumple con el requisito de que los usuarios autenticados vean los resultados de inmediato. La desventaja es que necesitará mantener la duración/TTL de la caché lo suficientemente pequeña para que su caché no se inunde pero lo suficientemente grande como para que los usuarios anónimos puedan obtener algún beneficio de ella.

Otra alternativa es escribir su propio filtro de acción para hacer el almacenamiento en caché, y agregar soporte allí para el almacenamiento en caché solo-anónimo. Sin embargo, esto es mucho más en el territorio de "roll your own". Ver Klopfenstein's old post o Steve Sanderson's en esto como punto de partida. Carecen de muchas de las otras características de OutputCache (por ejemplo, claves en toda la información de la ruta), pero puedes hacerlo funcionar según tus propias especificaciones.

5

Utilice esto como un filtro de acción global.

public class NoCacheForAuthenticatedUsersAttribute: ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if(filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     } 
    } 
} 
+1

Parece que no funciona para mí. Una vez que la página se coloca en el caché de salida, la lógica del atributo no se ejecutará. –

+0

Tal vez falte la devolución de llamada de validación httpContext.Response.Cache.AddValidationCallback – qub1n

Cuestiones relacionadas