Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Prevent your Silverlight XAP File from Caching in your Browser

0.00/5 (No votes)
6 Jan 2011 1  
This article describes how to prevent your Silverlight XAP file from caching in your browser.

Introduction

If you work with Silverlight daily, then you have run into this problem. Your XAP file has been cached in your browser and you have to empty your browser cache to resolve it. This is extremely frustrating for you and your customers. You may typically solve it by:

Go to Options –> Clear Browsing History –> Empty the Cache and finally click Clear Browsing data.

That's a Lot of Steps, Dude.

As you can see, this is a lot of unnecessary steps. It is even worse when you have a customer that says, “I can't see the new features you just implemented!” and you realize it’s a cached xap problem. I have been struggling with a way to prevent my XAP file from caching inside of a browser for a while now and decided to implement the following solution.

  1. If the Visual Studio Debugger is attached, then add a unique query string to the source param to force the XAP file to be refreshed.
  2. If the Visual Studio Debugger is not attached, then add the source param as Visual Studio generates it. This is also in case I forget to remove the above code in my production environment.
  3. I want the ASP.NET code to be inline with my .ASPX page. (I do not want a separate code behind .cs page or .vb page attached to the .aspx page.)

A Look at the Default Page Generated by Visual Studio

Below is an example of the hosting code generated when you create a new Silverlight project. As a quick refresher, the hard coded param name = “source” specifies the location of your XAP file.

 <form id="form1" runat="server" style="height:100%"> 
<div id="silverlightControlHost">
    <object data="data:application/x-silverlight-2," 
	type="application/x-silverlight-2" width="100%" height="100%">
      <param name="source" value="ClientBin/SilverlightApplication2.xap"/>
      <param name="onError" value="onSilverlightError" />
      <param name="background" value="white" />
      <param name="minRuntimeVersion" value="4.0.50826.0" />
      <param name="autoUpgrade" value="true" />
      <a href=http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0 
	style="text-decoration:none">
           <img src=http://go.microsoft.com/fwlink/?LinkId=161376 
		alt="Get Microsoft Silverlight" style="border-style:none"/>
      </a>
    </object><iframe id="_sl_historyFrame" 
	style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</form> 

So, How Can We Make It Better?

We are going to use a little bit of inline ASP.NET to generate the param name = source dynamically to prevent the XAP file from caching. Let's look at the completed solution:

<form id="form1" runat="server" style="height:100%">
   <div id="silverlightControlHost">
       <object data="data:application/x-silverlight-2," 
           type="application/x-silverlight-2" width="100%" height="100%">
       <%
           string strSourceFile = @"ClientBin/SilverlightApplication2.xap";
           string param;    
           if (System.Diagnostics.Debugger.IsAttached)
               //Debugger Attached - Refresh the XAP file.
               param = "<param name=\"source\" value=\"" + strSourceFile + "?" + 
                   DateTime.Now.Ticks + "\" />";
           else
           {
               //Production Mode 
               param = "<param name=\"source\" value=\"" + strSourceFile + "\" />";
           }
           Response.Write(param);
        %> 
         <param name="onError" value="onSilverlightError" />
         <param name="background" value="white" />
         <param name="minRuntimeVersion" value="4.0.50826.0" />
         <param name="autoUpgrade" value="true" />
         <a href=http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0 
		style="text-decoration:none">
              <img src=http://go.microsoft.com/fwlink/?LinkId=161376 
		alt="Get Microsoft Silverlight" style="border-style:none"/>
         </a>
       </object><iframe id="_sl_historyFrame" 
	style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</form>

We add the location to our XAP file to strSourceFile and if the debugger is attached, then it will append DateTime.Now.Ticks to the XAP file source and force the browser to download the .XAP. If you view the page source of your Silverlight Application, then you can verify it worked properly by looking at the param name = “source” tag as shown below:

<span class="Apple-style-span" style="font-size: 11px; line-height: normal; ">
<param name="source" value="ClientBin/SilverlightApplication2.xap?634299001187160148" />
</span>

If the debugger is not attached, then it will use the standard source tag as shown below:

<param name="source" value="ClientBin/SilverlightApplication2.xap"/>

What if I Want this Functionality in my Production Silverlight Application?

At this point you may be asking, how do I prevent my XAP file from being cached on my production app? Well, you have two easy options:

  1. I really don’t recommend this approach but you can force the XAP to be refreshed everytime with the following code snippet:
    <param name="source" 
        value="ClientBin/SilverlightApplication2.xap?<%=Guid.NewGuid().ToString() %>"/>

    NOTE: You could also substitute the “Guid.NewGuid().ToString() for anything that creates a random field. (I used DateTime.Now.Ticks earlier).

  2. Another solution that I like even better involves checking the XAP Creation Date and appending it to the param name = source. This method was described by Lars Holm Jenson.
<%
    string strSourceFile = @"ClientBin/SilverlightApplication2.xap";
    string param;
    if (System.Diagnostics.Debugger.IsAttached)
        param = "<param name=\"source\" value=\"" + strSourceFile + "\" />";
    else
    {
        string xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + strSourceFile;
        DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
        param = "<param name=\"source\" value=\"" + strSourceFile + "?ignore="
                + xapCreationDate.ToString() + "\" />";
    }
    Response.Write(param);
%>

As you can see, this problem has been solved. It will work with all web browsers and stubborn proxy servers that are caching your .XAP.

I Like Your Articles, Where Can I Find More of Them?

If you enjoyed this article, then check out my blog for others like this. You may also want to subscribe to my blog or follow me on Twitter.

alt Subscribe to my feed

History

  • 6th January, 2011: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here