views:

5556

answers:

14

When working with Silverlight, I've noticed that Firefox will cache the XAP file, so if I do an update, a user may be stuck using an outdated version. Is there a way to force the browser to either re-download the XAP file every time, or maybe only force it to after an update has been published? Or is there a setting in the Silverlight config that stops the browser from caching the XAP file altogether?

Thanks, jeff

+2  A: 

You could send HTTP headers to prevent it from caching:

Cache-control: no-cache
Pragma: no-cache

How you do this depends on the web server you're using.

Jarett
I tried this -- it does not appear to work.
Timothy Lee Russell
Timothy: You have to make sure those HTTP headers apply to the XAP file, not the HTML page. IIS lets you configure custom headers per folder: http://support.microsoft.com/kb/247404
Jason Orendorff
+3  A: 

You might find the Caching Tutorial for Web Authors and Webmasters helpful. This document discusses the different caches through which the client and server interact (browser, proxy, gateway) and how caching can be controlled.

converter42
How does this answer the question? It doesn't address the specific issues of XAP files.
KevDog
KevDog: If, as Timothy Lee Russell says in his answer, clearing Firefox's cache fixes this, then that means Firefox (not the Silverlight plug-in) is requesting the file over HTTP just like any other Web resource and caching it using the same rules that apply to all content. Understanding the caching rules might help.
Jason Orendorff
A: 

Hi Jeff,

We are also in the same situation wherein we want to control when the .XAP file gets downloaded to the browser.

An approach that you might want to take a look at is to use the Silverlight Isolated Storage as a "cache" to store your .XAP files.

Check out this blog: IsolatedStorage as a Silverlight object cache

ptio
@ptio Altought that does change the way the cache is being mantained it doesn't provide a way to know if an update has been made on the server, and that is due to silverlight code is run on the client and is not aware of a file on the server. You would have to use Isostorage to control the Date of the Downloaded Assemblies
Gabriel Guimarães
A: 

A super simple idea: just add a fake query string to the url.

<param name="source" value="app.xap?r12345"/>

Most servers should ignore it and server the file normally--depends on your server. If you get really clever, you could make the hosting page dynamic and automatically append a tick-count or date-time string to the query string. This ensures that you get caching when you want it, but force a download when there's a change.

Ideally, your server should do this for you. But if not...

kevmoo
I tried this -- it does not appear to work.
Timothy Lee Russell
It will work the first time, but not on subsequent requests, the query string value needs to be dynamic.
KevDog
A: 

I had this issue so now when I start a new application I set the assembly version to 0.0.0.1 and just update it by one on every deployment, seems to have solved it for me. Then just set it back to 1.0.0.0 on release.

David Casey
+1  A: 

So far, the only solution that I have found, once the problem occurs, is to clear the Firefox cache.

A better solution would be much better.

Timothy Lee Russell
This is important b/c it is the only way to -fix- the problem. Rather than focusing on preventing the problem. There is some data that you want to normally cache.. but as a developer you want to get the new copy.
ftrotter
+1  A: 

I'm getting this to work by a combination of the suggestions above:

  1. Set meta tag cache-control/pragma http-equiv attributes to 'No-Cache'
  2. Use an ASP.NET page to host the silverlight control (as opposed to an html page)
  3. Set the Source property of the ASP.NET Silverlight control in the code behind, appending a time stamp to the .xap url e.g.

    Silverlight1.Source = "ClientBin/MyApplication.xap?" + DateTime.Now.ToString("dd-MM-yy-HH:mm:ss");

+1  A: 

Another solution would be to append the version of the XAP file rather than a timestamp. The timestamp would change every time (might as well turn off caching). To get it to only change when the XAP has been updated would be to take some info from the XAP file. Am still looking into what I could use, perhaps the last modified datestamp of the XAP file?

Stephen Price
This is the best solution. It's mad to force the user to download the app every time using a random url.
FlappySocks
+7  A: 

Simplest way:

<param name="source" value="ClientBin/App.xap?<%= DateTime.Now.Ticks %>" />
INinjaAndy
It would be much better to take the file date of the xap file instead. Then users would not have to download the app every time.
FlappySocks
How do you do that from codebehind, and insert that into the html page in place of the DateTime? Example please.
Stephen Price
You can give the param element an id and a runat="server" attribute to access it in code behind. Assuming id="SourceParam":SourceParam.Attributes["value"] += "?" + DateTime.Today.Ticks;
INinjaAndy
+12  A: 

The query string works perfectly, but I wouldn't use DateTime.Now, because it forces the user to re-download the app every time. Instead, we use the following:

protected void Page_Load(object sender, EventArgs e)
{
    var versionNumber = Assembly.GetExecutingAssembly().GetName().Version.ToString();
    this.myApp.Source += "?" + versionNumber;
}

This way all you have to do is increment the version number in the AssemblyInfo.cs file.

Gromix
+2  A: 

This is what I do in php.

<?php $fdate = date("dHis",filemtime("MyApp.xap")) ?>

<param name="source" value="MyApp.xap?=<?php echo $fdate ?>"/>

The cache only gets updated when the app is actually updated.

FlappySocks
A: 

You can append the source url in the object tag with the last-write date of the XAP file. Check the code at my blog.

Lars Holm Jensen
A: 

The query string idea doesn't work for me in Silverlight 4. The server seems to cache the darned xap (though not the aspx file). The solution that does work in SL4 is to go to properties on your Silverlight project, go to Assembly info and put in a version.

christoban
A: 

Adding the timestamp for the XAP worked for me (I'm adding the SL control in javascript but this could just as easily be done inline):

var appTimestamp = '<%= System.IO.File.GetLastWriteTime(Server.MapPath("ClientBin/MyApp.xap")) %>';
var source = 'ClientBin/MyApp.xap?appTimestamp=' + appTimestamp;
Chris Cairns