Click here to Skip to main content
15,868,016 members
Articles / Programming Languages / C#

Prevent your Silverlight XAP File from Caching in your Browser

Rate me:
Please Sign up or sign in to vote.
4.55/5 (11 votes)
6 Jan 2011CPOL3 min read 54.3K   16   11
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.

Image 1

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.

XML
 <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:

XML
<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:

Image 2
XML
<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:

XML
<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:
    XML
    <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.
ASP.NET
<%
    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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Telerik
United States United States
Michael Crump is a Silverlight MVP and MCPD that has been involved with computers in one way or another for as long as he can remember, but started professionally in 2002. After spending years working as a systems administrator/tech support analyst, Michael branched out and started developing internal utilities that automated repetitive tasks and freed up full-time employees. From there, he was offered a job working at McKesson corporation and has been working with some form of .NET and VB/C# since 2003.

He has worked at Fortune 500 companies where he gained experience in embedded systems design and software development to systems administration and database programming, and everything in between.

His primary focus right now is developing healthcare software solutions using Microsoft .NET technologies. He prefers building infrastructure components, reusable shared libraries and helping companies define, develop and automate process standards and guidelines.

You can read his blog at: MichaelCrump.net or follow him on Twitter at @mbcrump.

Comments and Discussions

 
GeneralReduce XAP size zip caching Pin
diego mesa tabares22-Jan-13 3:02
diego mesa tabares22-Jan-13 3:02 
QuestionIt does not help for OOB. Pin
Member 39374611-Dec-12 1:07
Member 39374611-Dec-12 1:07 
AnswerRe: It does not help for OOB. Pin
Member 39374611-Dec-12 1:42
Member 39374611-Dec-12 1:42 
QuestionUseful one Pin
urinspiration26-Nov-12 19:35
urinspiration26-Nov-12 19:35 
QuestionRazor version (cshtml) Pin
ronnotel15-May-12 4:55
ronnotel15-May-12 4:55 
GeneralMy vote of 5 Pin
Farkhod15-Mar-12 18:41
Farkhod15-Mar-12 18:41 
GeneralMy vote of 5 Pin
Pat Tormey3-Feb-11 1:57
Pat Tormey3-Feb-11 1:57 
GeneralGREAT 5 Starts Pin
Pat Tormey3-Feb-11 1:56
Pat Tormey3-Feb-11 1:56 
GeneralMy vote of 5 Pin
ACanadian10-Jan-11 5:16
ACanadian10-Jan-11 5:16 
GeneralMy vote of 4 Pin
butchzn6-Jan-11 22:57
butchzn6-Jan-11 22:57 
GeneralRe: My vote of 4 Pin
mbcrump7-Jan-11 8:34
mentormbcrump7-Jan-11 8:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.