net mvc microsoft cache asp c# asp.net-mvc iis-7 http-headers cache-control

c# - microsoft - outputcache mvc 5



Control de caché: no-store, must-revalidate no enviado al navegador del cliente en IIS7+ASP.NET MVC (2)

Estoy tratando de asegurarme de que una determinada página nunca se almacene en caché, y nunca se muestre cuando el usuario haga clic en el botón Atrás. Esta respuesta altamente calificada (actualmente 1068 upvotes) dice usar :

Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); Response.AppendHeader("Pragma", "no-cache"); Response.AppendHeader("Expires", "0");

Sin embargo, en IIS7 / ASP.NET MVC, cuando envío esos encabezados, el cliente ve estos encabezados de respuesta:

Cache-control: private, s-maxage=0 // that''s not what I set them to Pragma: no-cache Expires: 0

¿Qué pasó con el encabezado de control de caché? ¿Se sobreescribe algo nativo de IIS7 o ASP.NET? He comprobado mi solución y no tengo ningún código que sobrescriba este encabezado.

Cuando agrego Response.Headers.Remove("Cache-Control"); Primero, no hace ninguna diferencia.

Response.Headers.Remove("Cache-Control"); Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); Response.AppendHeader("Pragma", "no-cache"); Response.AppendHeader("Expires", "0");

Cuando agrego un atributo [OutputCache] :

[OutputCache(Location = OutputCacheLocation.None)] public ActionResult DoSomething() { Response.Headers.Remove("Cache-Control"); Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); Response.AppendHeader("Pragma", "no-cache"); Response.AppendHeader("Expires", "0"); var model = DoSomething(); return View(model); }

Luego los encabezados de respuesta del cliente cambian a:

Cache-control: no-cache Pragma: no-cache Expires: 0

Que está más cerca, pero todavía no son los encabezados que quiero enviar. ¿Dónde se anulan estos encabezados y cómo puedo detenerlos?

EDITAR: He comprobado y los encabezados incorrectos se están enviando a Chrome, FF, IE y Safari, por lo que parece ser un problema del servidor, no un problema relacionado con el navegador.


A través de prueba y error, he encontrado que una forma de configurar los encabezados correctamente para IIS7 en ASP.NET MVC es:

Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.AppendCacheExtension("no-store, must-revalidate"); Response.AppendHeader("Pragma", "no-cache"); Response.AppendHeader("Expires", "0");

La primera línea establece Cache-control en no-cache , y la segunda línea agrega los otros atributos no-store, must-revalidate .

Puede que esta no sea la única forma, pero proporciona un método alternativo si el Response.AppendHeader("Cache-control", "no-cache, no-store, must-revalidate"); más directo Response.AppendHeader("Cache-control", "no-cache, no-store, must-revalidate"); falla

Otras preguntas relacionadas con el control de caché de IIS7 que pueden resolverse con esto son:

  • Algo está forzando que las respuestas tengan control de caché: privado en IIS7
  • IIS7: configuración de caché no funciona ... ¿por qué?
  • Los encabezados de almacenamiento en caché del cliente MVC de IIS7 + ASP.NET no funcionan
  • Establecer el control de caché para las páginas aspx
  • Control de caché: no-store, must-revalidate no enviado al navegador del cliente en IIS7 + ASP.NET MVC

Quiero añadir algo a la respuesta de :
Si está configurando el control de caché en un valor más restrictivo de lo que ya es , está bien. (es decir, configurando no-cache, cuando es privado)

Pero, si desea establecer un valor menos restrictivo de lo que ya es ( es decir, establecerlo en privado, cuando no hay caché), el siguiente código no funcionará:

Response.Cache.SetCacheability(HttpCacheability.Private);

Porque, el método SetCacheablitiy tiene este código a continuación y establece el indicador de caché solo si es más restrictivo:

if (s_cacheabilityValues[(int)cacheability] < s_cacheabilityValues[(int)_cacheability]) { Dirtied(); _cacheability = cacheability; }

Para superar esto en .net mvc, necesita obtener una instancia de HttpResponseMessage y asignar un CacheControlHeaderValue a su valor Headers.CacheControl :

actionExecutedContext.Response.Headers.CacheControl = new CacheControlHeaderValue { MaxAge = TimeSpan.FromSeconds(3600), Private = true };

Una instancia de HttpResponseMessage está disponible en los filtros de acción. Puede escribir un filtro de acción para establecer valores de encabezado de caché como este:

public class ClientSideCacheAttribute : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { var response = actionExecutedContext.ActionContext.Response; response.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue { MaxAge = TimeSpan.FromSeconds(9999), Private = true, }; } }