tag route net for data asp all asp.net-mvc asp.net-mvc-4 resourcebundle

asp.net-mvc - net - asp-route



Caché de cliente de paquete MVC (6)

El comportamiento predeterminado de la función de asociación de ASP.NET MVC es que si alguno de los archivos que componen un paquete cambia, la cadena de consulta para ese paquete cambiará automáticamente, suponiendo que esté utilizando lo siguiente en el código de su vista:

@Scripts.Render("bundle name")

Esto significa que si tiene una nueva versión de un archivo que está en un paquete, la próxima vez que su página muestre una vista que use ese paquete, enviará una etiqueta de script que el navegador del cliente no encontrará en su caché (ya que cadena de consulta es diferente).

Entonces parece que esto resolverá su problema, depende de lo que usted quiera decir:

y no cambiarán la url que apunta a mi paquete cada vez que lo cambio

Por defecto, un paquete de MVC se almacena en caché en el cliente durante 1 año. ¿Es posible configurar sus encabezados de cliente de forma manual (para 1 paquete específico)?

Lo que necesito es establecer encabezados de caducidad personalizados para uno de mis paquetes. No puedo confiar en la cadena de consulta "v = hash" porque este paquete es para un sitio web externo, y no cambiarán la url que apunta a mi paquete cada vez que lo modifique.

Lo que he intentado es crear una clase Bundle personalizada (heredar Bundle) y anular el método GenerateBundleResponse (). De esta forma puedo controlar el almacenamiento en caché del servidor, pero la única manera de personalizar el almacenamiento en caché del cliente es establecer BundleResponse.Cacheability (público, privado, nocache, etc.). Pero no puedo configurar encabezados manualmente. Tengo acceso a BundleContext (y es HttpContext), pero cuando establezco encabezados en ese contexto, tendrá efecto para todas las demás solicitudes también.


Esta es una modificación de la respuesta de Adilson, pero sin tener que crear un HttpModule:

En global.asax.cs del proyecto MVC:

protected void Application_EndRequest(object sender, EventArgs e) { if (Request.RawUrl.Contains("/bundles/")) { // My bundles all have a /bundles/ prefix in the URL Response.Cache.SetExpires(DateTime.Now.AddHours(2)); } }


Lo que parece funcionar para mí es darle al paquete un número de versión en la configuración del paquete, luego hacer referencia a la nueva versión en su marcado.



Si bien no existe una mejor manera de configurar la capacidad de almacenamiento en caché de los paquetes, puede crear un HttpModule que identifique las solicitudes al paquete y establezca la caché de contenido.

Tiene el mismo efecto al hacer esto en Global.asax:

public override void Init() { this.EndRequest += MvcApplication_EndRequest; base.Init(); } void MvcApplication_EndRequest(object sender, EventArgs e) { var request = this.Request; var response = this.Response; if (request.RawUrl.Contains("Content/")) { response.Cache.SetCacheability(HttpCacheability.NoCache); } }


Lamentablemente no hay forma. Puede encontrar el motivo en la implementación interna de la agrupación. en la clase BundleHandler ProcessRequest llama al ProcessRequest , método interno de la clase Bundle y llama a SetHeaders justo antes de HttpContext.Response.Write . Por lo tanto, el caché del cliente se establece en un año justo antes de la escritura de respuesta.

Nota: BundleHandler es una clase internal sealed class BundleHandler : IHttpHandler : clase internal sealed class BundleHandler : IHttpHandler

En la clase BundleHandler :

public void ProcessRequest(HttpContext context) { if (context == null) { throw new ArgumentNullException("context"); } context.Response.Clear(); BundleContext context2 = new BundleContext(new HttpContextWrapper(context), BundleTable.Bundles, this.BundleVirtualPath); if (!Bundle.GetInstrumentationMode(context2.HttpContext) && !string.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"])) { context.Response.StatusCode = 304; } else { this.RequestBundle.ProcessRequest(context2); } }

En la clase Bundle :

internal void ProcessRequest(BundleContext context) { context.EnableInstrumentation = GetInstrumentationMode(context.HttpContext); BundleResponse bundleResponse = this.GetBundleResponse(context); SetHeaders(bundleResponse, context); context.HttpContext.Response.Write(bundleResponse.Content); } private static void SetHeaders(BundleResponse bundle, BundleContext context) { if (bundle.ContentType != null) { context.HttpContext.Response.ContentType = bundle.ContentType; } if (!context.EnableInstrumentation) { HttpCachePolicyBase cache = context.HttpContext.Response.Cache; cache.SetCacheability(bundle.Cacheability); cache.SetOmitVaryStar(true); cache.SetExpires(DateTime.Now.AddYears(1)); cache.SetValidUntilExpires(true); cache.SetLastModified(DateTime.Now); cache.VaryByHeaders["User-Agent"] = true; } }