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,
};
}
}