Tuesday, January 29, 2013

Making the Silverlight XAP file expire from browser cache programmatically

Making the Silverlight XAP file expire from browser cache programmatically

How to do I prevent a Silverlight XAP file being cached by the web browser?

The reason I want to do this is during development I don't want to manually clear the browser cache, I'm looking for a programmatic approach server side.

Cheers

AWC

Answers & Comments...

Answer: 1

Add a query parameter to the URL for the XAP in the element on the HTML Page:

  • clientBin/MyApp.xap?rev=1
  • clientBin/MyApp.xap?rev=2

It will be ignored and break the cache. In IE8, there are some cache management tools: Open the Developer tools:

  • Try Cache...Always Refresh from Server
  • Try Cache...Clear Browser Cache for this domain...
by : Michael S. Scherotterhttp://stackoverflow.com/users/27306

Answer: 2

Using IIS management add a custom header Cache-Control with the value no-cache. That'll cause the browser to check that any cached version of the XAP is the latest before using it.

by : AnthonyWJoneshttp://stackoverflow.com/users/17516

Answer: 3

Create a custom http handler for handling *.xap files and then set your caching options inside the handler.

Something like this...

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;     } } 
by : David Cooperhttp://stackoverflow.com/users/616875

Answer: 4

The solution presented here is somewhat similar to Michael's but is automatic and guarantees the client will always get a new version. This may be inefficient depending on your situation.

Since Lars says in his comments that he is not on Stack Overflow, I'm copying the response here.

<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> 
by : Jedidjahttp://stackoverflow.com/users/9913

Answer: 5

Well all the above examples depend on the browser NOT caching the HTML that contains the new trick xap name.... so you just move the problem on to something else. And they are also fiendishly complicated....

However for the debugging case, at least, it's easy to write the <object> and <param> tags in javascript so that the name changes every time the html page is used, whether it's cached by the browser or not!

<script type="text/javascript">    document.write('<object blah blah >');    document.write('<param name="Source" value="myapp.xap?'                + new Date().getTime()+'">');    document.write('</object>');  </script> 

This sidesteps any hassle you may have controlling server settings and works just as well regardless of the server technology in use.

Note: you have to write the whole object group with the same method because putting a script tag inside the object tag means "only do this if the browser doesnt support the object.

by : Chris Harlowhttp://stackoverflow.com/users/813094

Answer: 6

I added a query parm to the path of the xap file, so that I can manage it through Versioning.

Default.aspx code:

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

Default.aspx.cs code:

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()     } } 
by : Big Chickenhttp://stackoverflow.com/users/2022512




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog