2009-09-17 20 views
5

Estoy tratando de utilizar OutputCaching en mi sitio web ASP.NET MVC. El problema es que cuando trato de cambiar el valor de uno de mis parámetros de cadena de consulta, ¡devuelve los datos para el primer elemento que se solicitó!El almacenamiento en caché no funciona bien en mi sitio web ASP.NET MVC?

Aquí está mi código (con los nombres cambiados) param ...

[ApiAuthorize] 
[HandleErrorAsJson] 
public class SearchController : Controller 
{ 
    [AcceptVerbs(HttpVerbs.Get)] 
    [OutputCache(Duration = 60, VaryByParam = "*")] 
    public ActionResult ScoreCard(string foo, byte? bar, byte? pewpew) 
    { 
    .. 
    } 
} 
  • NOTA 1: ApiAuthorize - atributo personalizado que comprueba si un parámetro de cadena de consulta llamado 'clave' y comprueba en el diccionario de una memoria, para ver si existe
  • NOTA 2: HandleErrorAsJson - atributo personalizado que devuelve el mensaje de error como json si se lanzó/se arroja una excepción.

y aquí es una llamada a la muestra que estoy haciendo a esta acción: -

por lo que los datos de la primera llamada (foo = hola mundo, Pew Pew) se devuelve como 200 OK. Luego, la segunda llamada api devuelve un 200 OK pero con los datos de la llamada anterior.

Además, no estoy utilizando ningún servidor proxy. Si comento el atributo OutputCache, todo está bien.

También he probado los siguientes (lista manualmente cada vez que necesito caché) .....

[OutputCache(Duration = 60, VaryByParam = "foo,key,bar,pewpew")] 

No hubo suerte :(

Aviso cómo necesito para asegurarse de que i incluir el parámetro API 'clave' como parte de la clave única de caché. No quiero que las personas busquen lo mismo, pero si la segunda persona no tiene la clave correcta, no deberían obtener un resultado en caché , pero un mensaje de error (técnicamente, es un 401 no autorizado, pero de todos modos) ...

Thou ghts?

Respuesta

4

Se supone que la lista de parámetros en VaryByParam está delimitada por punto y coma, no delimitada por comas. Pruébalo. Dicho eso, el * debería haber funcionado.

+0

+1 más se centró directamente en la pregunta de la mano. aunque no creo que sea el único problema que tiene aquí. respondió a su comentario a continuación también. – dove

0

Uso un filtro para el almacenamiento en caché de resultados que dará control programático para la depuración y también establecerá cuándo debe ser. No dude en utilizar esto y ver si la configuración aquí haría la diferencia, que yo creo que puede (también asegurarse de que cualquier almacenamiento en caché anterior se borra)

public class CacheFilterAttribute : ActionFilterAttribute 
    { 
     private const int Second = 1; 
     private const int Minute = 60 * Second; 
     private const int Hour = 60 * Minute; 
     public const int SecondsInDay = Hour * 24; 


     /// <summary> 
     /// Gets or sets the cache duration in seconds. The default is 10 seconds. 
     /// </summary> 
     /// <value>The cache duration in seconds.</value> 
     public int Duration 
     { 
      get; 
      set; 
     } 

     public int DurationInDays 
     { 
      get { return Duration/SecondsInDay; } 
      set { Duration = value * SecondsInDay; } 
     } 

     public CacheFilterAttribute() 
     { 
      Duration = 10; 
     } 

     public override void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      if (Duration <= 0) return; 

      HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache; 
      TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration); 

      cache.SetCacheability(HttpCacheability.Public); 
      cache.SetExpires(DateTime.Now.Add(cacheDuration)); 
      cache.SetMaxAge(cacheDuration); 
      cache.AppendCacheExtension("must-revalidate, proxy-revalidate"); 
     } 
    } 

Sólo estoy usando esto hasta ahora para una parte muy estática de un sitio, por lo que tiene una llamada como esta

[CacheFilter(DurationInDays = 1)] 

Es obvio que acababa de extender esto para tener VaryByParams expone como una propiedad, puede proporcionar, pero suena como usted sabría qué hacer.

+0

Fuera de interés, ¿por qué terminaste creando tu propio atributo aquí? –

+0

Solicité un par de visitas y haré más. No estaba al 100% en las configuraciones exactas que ves arriba, así que con esto puedo modificar fácilmente y saber que se aplicó en todas partes.Todavía no estoy seguro de si agregar más encabezados al configurar la caché. Por supuesto, si encuentro que esta es una mala idea, puedo hacer de esto una extensión limpia del atributo OutputCache y no perder nada. En resumen, tenía algo que ganar con un camino claro hacia la seguridad si surgía algún riesgo. – dove

+0

No hay nada malo con lo que ha hecho aquí, pero no responde a su pregunta. El filtro que ha creado afecta al * caché del navegador *, no al caché del servidor. Eso es legítimo, y no tengo conocimiento de nada incorporado en ASP.NET MVC que lo haga. También, implícitamente, hace un buen punto, que es que aquí hay dos cachés diferentes en juego, uno en el navegador y el otro en el servidor. Me parece que su pregunta está relacionada con el caché del servidor, aunque sería bueno comprobar esto con Firebug o Fiddler. –

Cuestiones relacionadas