Hacer que el archivo XAP de Silverlight caduque de forma programada desde el caché del navegador
browser caching (7)
¿Cómo puedo evitar que el navegador web guarde en caché un archivo Silverlight XAP?
La razón por la que quiero hacer esto es durante el desarrollo. No quiero borrar manualmente el caché del navegador, estoy buscando un lado del servidor de enfoque programático.
Agregué un parm de consulta a la ruta del archivo xap, para poder gestionarlo a través del control de versiones.
Código Default.aspx :
<param
name="source"
value="ClientBin/MySilverLightApp.xap?xapid<%=XapID %>" />
Código predeterminado.aspx.cs :
protected string XapID
{
get
{
Version v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
if (System.Diagnostics.Debugger.IsAttached)
Response.Write(string.Format("Build: {0}.{1}.{2}.{3}", v.Major.ToString(), v.Minor.ToString(), v.Build.ToString(), v.Revision.ToString()));
return string.Format("{0}.{1}.{2}.{3}", v.Major.ToString(), v.Minor.ToString(), v.Build.ToString(), v.Revision.ToString()
}
}
Agregue un parámetro de consulta a la URL para el XAP en el elemento en la página HTML:
- clientBin / MyApp.xap? rev = 1
- clientBin / MyApp.xap? rev = 2
Se ignorará y romperá el caché. En IE8, hay algunas herramientas de administración de caché: Abre las herramientas de desarrollo:
- Pruebe Caché ... Siempre actualice desde el servidor
- Prueba Caché ... Borrar caché del navegador para este dominio ...
Bueno, todos los ejemplos anteriores dependen de que el navegador NO almacene en la memoria caché el HTML que contiene el nuevo nombre trick xap .... por lo que simplemente mueve el problema a otra cosa. Y también son diabólicamente complicados ...
Sin embargo, para el caso de depuración, al menos, es fácil escribir las etiquetas <object> y <param> en javascript para que el nombre cambie cada vez que se usa la página html, ¡ya sea que el navegador la guarde en caché!
<script type="text/javascript">
document.write(''<object blah blah >'');
document.write(''<param name="Source" value="myapp.xap?''
+ new Date().getTime()+''">'');
document.write(''</object>'');
</script>
Esto evita cualquier problema que pueda tener el control de la configuración del servidor y funciona igual de bien independientemente de la tecnología de servidor en uso.
Nota: debe escribir todo el grupo de objetos con el mismo método porque colocar una etiqueta de script dentro de la etiqueta de objeto significa "solo hacer esto si el navegador no admite el objeto".
Cree un controlador http personalizado para manejar archivos * .xap y luego configure sus opciones de almacenamiento en caché dentro del controlador.
Algo como esto...
using System;
using System.IO;
using System.Web;
public class FileCacheHandler : IHttpHandler
{
public virtual void ProcessRequest(HttpContext context)
{
if (File.Exists(context.Request.PhysicalPath))
{
DateTime lastWriteTime = File.GetLastWriteTime(filePath);
DateTime? modifiedSinceHeader = GetModifiedSinceHeader(context.Request);
if (modifiedSinceHeader == null || lastWriteTime > modifiedSinceHeader)
{
context.Response.AddFileDependency(filePath);
context.Response.Cache.SetLastModifiedFromFileDependencies();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.TransmitFile(filePath);
context.Response.StatusCode = 200;
context.Response.ContentType = "application/x-silverlight-app";
context.Response.OutputStream.Flush();
}
else
{
context.Response.StatusCode = 304;
}
}
}
public DateTime? GetModifiedSinceHeader(HttpRequest request)
{
string modifiedSinceHeader = request.Headers["If-Modified-Since"];
DateTime modifiedSince;
if (string.IsNullOrEmpty(modifiedSinceHeader)
|| modifiedSinceHeader.Length == 0
|| !DateTime.TryParse(modifiedSinceHeader, out modifiedSince))
return null;
return modifiedSince;
}
}
La solución presentada here es similar a la de Michael pero es automática y garantiza que el cliente siempre obtendrá una nueva versión. Esto puede ser ineficiente dependiendo de su situación.
Dado que Lars dice en sus comentarios que no está en , estoy copiando la respuesta aquí.
<object id="Xaml1" data="data:application/x-silverlight-2,
"type="application/x-silverlight-2" width="100%" height="100%">
<%––<param name="source" value="ClientBin/SilverlightApp.xap"/>––%>
<%
string orgSourceValue = @"ClientBin/SilverlightApp.xap";
string param;
if (System.Diagnostics.Debugger.IsAttached)
{
param = "<param name=/"source/" value=/"" + orgSourceValue + "/" />";
}
else
{
string xappath = HttpContext.Current.Server.MapPath(@"") + @"/" + orgSourceValue;
DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
param = "<param name=/"source/" value=/"" + orgSourceValue + "?ignore=" +
xapCreationDate.ToString() + "/" />";
}
Response.Write(param);
%>
....
</object>
No es muy raro encontrarse con el almacenamiento en caché .XAP, lo que significa que cada vez que implementa una nueva versión de la aplicación Silverlight, el navegador no descarga el archivo .XAP actualizado.
Una solución podría ser cambiar las propiedades de IIS. Puede activar la opción "Habilitar el encabezado HTTP de caducidad del contenido" para su archivo .XAP siguiendo estos pasos:
- Abra el Administrador de IIS
- Vaya a "Sitio web predeterminado" y encuentre el sitio web para su proyecto de Silverlight.
- Encuentra el archivo .XAP en ClientBin.
- Vaya a la página de propiedades del archivo .XAP, en la pestaña Encabezados HTTP, active "Permitir el vencimiento del contenido", haga clic en el botón de opción "Caducar inmediatamente".
- Guarde los cambios.
De esta forma, se descargará el .XAP más reciente (solo si hay un archivo .XAP más reciente) cuando actualice su página sin tener que cerrar el navegador.
¡Espero que esto ayude!
Usando la administración de IIS, agregue un encabezado personalizado Cache-Control
con el valor no-cache
. Eso hará que el navegador verifique que cualquier versión almacenada en caché de XAP sea la última antes de usarla.