2010-02-17 29 views

Respuesta

26

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.

+0

Esta es una gran respuesta y mucho mejor que muchas otras (he visto dar esta respuesta aquí muchas veces.) Soy nuevo en el desarrollo web, pero después de leer el tutorial a continuación ... Puedo ver que esto es exactamente lo que es necesario para el almacenamiento en caché de XAP. Realmente es una gran solución. [Tutorial sobre almacenamiento en caché] (http://www.mnot.net/cache_docs/) –

+0

¿No obligaría esto al navegador a no almacenar nunca en caché el XAP? ¿O se asegura de que solo se almacena en caché cuando el XAP es idéntico? –

+0

¿Hay alguna manera de hacerlo a través de Web.Config? Mi proyecto está alojado en un servidor donde no tengo acceso a la administración de IIS. – Marlon

7

Añadir un parámetro de consulta a la URL del 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 gestión de caché: Abrir las Herramientas para desarrolladores:

  • Try caché ... Siempre Actualizar desde el servidor
  • Try caché ... Borrar la caché del navegador para este dominio ...
+0

Los números de revisión en recursos estáticos pueden ser bastante efectivos cuando las URL que los hacen referencia se generan dinámicamente para que pueda agregar estas referencias. Sin embargo, se necesita bastante infraestructura personalizada para que esto suceda de forma dinámica y sin eso el desarrollador debe recordar actualizar el número de versión manualmente. Se empeora si el recurso se usa en varios lugares. Dado que no es probable que los XAP sean solicitados a alta frecuencia por un cliente individual, la respuesta "no modificada" ocasional es más deseable. – AnthonyWJones

5

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

la solución presentada here es algo similar a Michael, pero es automático y garantiza que el cliente siempre tendrá una nueva versión. Este puede ser ineficiente dependiendo de su situación.

Dado que Lars dice en su comments that he is not on Stack Overflow, 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> 
+0

Di un vistazo a este método y aunque puedo depurar y ver el 'param' correctamente, Response.Write escribe en mi ejemplo sobre el comienzo de la etiqueta . ¿Alguna idea sobre cómo resolver esto? – dougajmcdonald

+0

Eh ... eso es realmente extraño. Tal vez podrías Response.Write la etiqueta del objeto completo, incluido el param? – Jedidja

+0

Es realmente extraño, pensé en escribir todo el lote, lo cual hice. Parece que hay un marco que estamos usando que no maneja respuestas.writes en la ubicación que están en la corriente aspx/Response. Levantaré una llamada con ellos y veré si pueden señalarme en la dirección de escritura. Gracias por la respuesta – dougajmcdonald

2

bien todos los ejemplos anteriores dependen de que el navegador no almacenar en caché el código HTML que contiene el nombre nuevo truco XAP .... por lo que sólo hay que mover el problema a otra cosa. Y también se complican diabólicamente ....

Sin embargo, para el caso de depuración, al menos, es fácil para escribir el objeto < > y <param> etiquetas de Javascript para que el nombre cambia cada vez que la página HTML es usado, ya sea que esté en la memoria caché del navegador o no!

<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 deja de lado ningún tipo de molestia que pueda tener el control de la configuración del servidor y funciona igual de bien con independencia de la tecnología de servidores en uso.

. Nota: tienes que escribir todo el grupo objeto con el mismo método, ya que pone una etiqueta de script dentro de la etiqueta objeto significa "solamente hacer esto si el navegador no apoya el objeto

5

he añadido un Parm consulta a la ruta del archivo xap, para que pueda gestionarlo a través del control de versiones.

Default.aspx código:

<param 
    name="source" 
    value="ClientBin/MySilverLightApp.xap?xapid<%=XapID %>" /> 

Default.aspx.cs código:

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() 
    } 
} 
2

No es muy raro encontrarse con .xap almacenamiento en caché, lo que significa que cada vez 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. Se puede activar la opción “Activar cabecera HTTP contenido de caducidad” en su archivo .xap siguiendo estos pasos:

  1. Abra el Administrador de IIS
  2. Ir a “Sitio Web predeterminado” y encontrar el sitio web para su proyecto de Silverlight .
  3. Encuentra el archivo .XAP en ClientBin.
  4. Vaya a la página de propiedades del archivo .XAP, en la pestaña Encabezados HTTP, active "Permitir caducidad del contenido", haga clic en el botón de opción "Caducar inmediatamente".
  5. Guarde los cambios.

De esta manera, el último .XAP (solo si hay un archivo .XAP más reciente) se descargará cuando actualice su página sin tener que cerrar el navegador.

Espero que esto ayude!

Cuestiones relacionadas