net microsoft cache asp c# asp.net http caching

c# - cache - microsoft caching



¿Por qué HttpCacheability.Private suprime ETags? (3)

Mientras escribía un IHttpHandler personalizado encontré un comportamiento que no esperaba con respecto al objeto HttpCachePolicy.

Mi controlador calcula y establece una etiqueta de entidad (utilizando el método SetETag en HttpCachePolicy asociado con el objeto de respuesta actual). Si configuro el control de caché en público usando el método SetCacheability todo funciona como un amuleto y el servidor lo envía a lo largo del encabezado de etiqueta electrónica. Si lo configuro en privado, se suprimirá el encabezado de la etiqueta electrónica.

Tal vez simplemente no he buscado lo suficiente, pero no he visto nada en la especificación HTTP / 1.1 que justifique este comportamiento. ¿Por qué no desea enviar E-Tag a los navegadores al mismo tiempo que prohíbe que los servidores proxy almacenen los datos?

using System; using System.Web; public class Handler : IHttpHandler { public void ProcessRequest (HttpContext ctx) { ctx.Response.Cache.SetCacheability(HttpCacheability.Private); ctx.Response.Cache.SetETag("/"static/""); ctx.Response.ContentType = "text/plain"; ctx.Response.Write("Hello World"); } public bool IsReusable { get { return true; } } }

Volverá

Cache-Control: private Content-Type: text/plain; charset=utf-8 Content-Length: 11

Pero si lo cambiamos a público, volverá

Cache-Control: public Content-Type: text/plain; charset=utf-8 Content-Length: 11 Etag: "static"

He ejecutado esto en el servidor de desarrollo ASP.NET e IIS6 hasta el momento con los mismos resultados. Además, no puedo establecer explícitamente el ETag usando

Response.AppendHeader("ETag", "static")

Actualización : es posible agregar manualmente el encabezado ETag cuando se ejecuta en IIS7, sospecho que esto es causado por la estrecha integración entre ASP.NET y la interconexión IIS7.

Aclaración : es una pregunta larga, pero la pregunta central es esta: ¿por qué ASP.NET hace esto, cómo puedo solucionarlo y debería hacerlo?

Actualización : voy a aceptar la respuesta de Tony, ya que es esencialmente correcta (¡vete Tony!). Descubrí que si quieres emular HttpCacheability.Private por completo, puedes establecer la caché en ServerAndPrivate pero también tienes caché de llamadas. SetOmitVaryStar (true) de lo contrario, la memoria caché agregará el encabezado Vary: * al resultado y no desea eso. Voy a editar eso en la respuesta cuando obtenga permisos de edición (o si ves este Tony, ¿podrías editar tu respuesta para incluir esa llamada?)


Creo que necesitas usar HttpCacheability.ServerAndPrivate

Eso debería darte control de caché: privado en los encabezados y dejarte establecer un ETag.

La documentación sobre eso necesita ser un poco mejor.

Editar: Markus descubrió que también tiene caché de llamada. SetOmitVaryStar (verdadero) de lo contrario, el caché agregará el encabezado Vary: * a la salida y usted no quiere eso.


Desafortunadamente, si System.Web.HttpCachePolicy.UpdateCachedHeaders() en .NET Reflector, verás que hay una instrucción if que comprueba específicamente que Cacheability no es Privado antes de hacer algo de ETag. En cualquier caso, siempre he encontrado que Last-Modified/If-Modified-Since funciona bien para nuestros datos y de todos modos es un poco más fácil de monitorear en Fiddler.


Si, como yo, no está contento con la solución mencionada aquí de usar Cacheability.ServerAndPrivate, y realmente quiere usar Private, quizás porque está personalizando páginas individualmente para los usuarios y no tiene sentido almacenar en caché en el servidor, entonces al menos en .NET 3.5 puede establecer ETag a través de Response.Headers.Add y esto funciona bien.

Nota: si hace esto, tiene que implementar la comparación de los encabezados de los clientes usted mismo y el manejo de la respuesta HTTP 304, no estoy seguro de si .NET se ocupa de esto en circunstancias normales.