none
Silverlight xap caching?

    Question

  • I'm having a problem with updates to a silverlight application I deploy not being downloaded. If I put a xap on a web site and then goto the URL and use it for a while in IE, then deploy a new version of the xap and go back to the website in IE the browser never gets the updated XAP file until I delete my entire browser cache.

     

    I've gone to the project and tried incrementing the version of the assembly etc etc and nothing works. Anyone know how to version xaps like XBAPS use to be versioned?

    Tuesday, March 18, 2008 12:18 PM

All replies

  • I meet the same probelm. Is there any way to version xaps?

     Thanks

    Tuesday, March 18, 2008 7:15 PM
  • У меня такая же проблема. Я просто меняю название файла, в этом случаи приложение обновляется.

    Tuesday, March 18, 2008 7:54 PM
  • I'm also having this problem. Happens regardless of whether I hit my app thru an html or aspx files (which makes sense because it downloads the xap with a separate request).

    Maybe there's a way to configure IIS to issue special response headers that indicate cache directives for .xap requests?

    Wednesday, April 02, 2008 7:24 PM
  • You can turn the Enable Content Expiration HTTP header option on for your XAP file. Open IIS Manager, goto Default Web Site and find your Web site for the silverlight project. Find the XAP file under ClientBin. Goto the properties page of the XAP file, on HTTP Headers Tab, Turn on "Enable Content Expiration", click the "Expire Immediately" radio button. Save the change.

    This way the new XAP (only there is a new XAP) will get downloaded when you refresh your page without having to close the browser.

     


     

     

     

     

     

     

     

    Wednesday, April 02, 2008 9:36 PM
  • Why the silverlight is not caching when I'm making a call through passing InitParameters that value is coming from Request...?

    Cheers,Ricky

    Thursday, April 03, 2008 1:45 AM
  • Why the silverlight is not caching when I'm making a call through passing InitParameters that value is coming from Request...?
     

    I have answered your question in this post.

    Okay. I will paste the answer here again...

    No. It won't download xap file everytime if you cache it.

    For example:

    Application Name: SL2Cache and SL2Cache_Web

    SL2CacheTestPage.aspx 

    <%@ Page Language="C#" AutoEventWireup="true" %>

    <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"
        TagPrefix="asp" %>


    <%@ OutputCache Duration="60" VaryByParam="None" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">
    <head runat="server">
        <title>Test Page For SL2Cache</title>
    </head>
    <body style="height:100%;margin:0;">
        <form id="form1" runat="server" style="height:100%;">
            <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
            <div  style="height:100%;">
                <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SL2Cache.xap" InitParameters="id=00001" Version="2.0" Width="100%" Height="100%" />
            </div>
            <div> <% = System.DateTime.Now.ToString () %></div>
        </form>
    </body>
    </html>

    App.xaml.cs

     private void Application_Startup(object sender, StartupEventArgs e)
            {
                // Load the main control
                string id = e.InitParams["id"];
                this.RootVisual = new Page (id);

            }

    Page.xaml

    <UserControl x:Class="SL2Cache.Page"
        xmlns="http://schemas.microsoft.com/client/2007"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="400" Height="300">
        <Grid x:Name="LayoutRoot" Background="White">
            <TextBlock x:Name="displayTextBlock" />
        </Grid>
    </UserControl>

    Page.xaml.cs 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    namespace SL2Cache {
        public partial class Page :UserControl {
            public Page()
            {
                InitializeComponent ();
            }
            public Page(string arg)
            {
                InitializeComponent ();
                displayTextBlock.Text = arg;
            }

        }
    }


    Steps to Test:

    1.  Set InitParameters="id=00001" in SL2CacheTestPage.aspx

    2.  Run the application. I will see 00001 in Silverlight Content.

    3. Close the brower.

    4. Change   InitParameters="id=1111" in SL2CacheTestPage.aspx

    5. Run the application again.

    I will still able to see "00001" . It's because it cached it.

    You can test the different between ASP.NET page with cache and without cache by adding or removing this line "<%@ OutputCache Duration="60" VaryByParam="None" %>"  from SL2CacheTestPage.aspx

    Hope it helps.

     

    Thursday, April 03, 2008 2:24 AM
  • This way the new XAP (only there is a new XAP) will get downloaded when you refresh your page without having to close the browser.

     

    Mmmm....

    This means that next time the user hits the page it will download the new xap file, isn't?

    Or only if newer one no matter if he/she closes the browser and later come back to the page?

    On the other hand, is some way to set such header without IIS manager? In web.config? some kind of manifest in the xap file?

    I haven't access to it because I use hosting service.

    Regards. 

    Thursday, April 03, 2008 9:54 AM
  • I have one question.

    I am creating big silverlight application for my website.

    I am expecting the size of XAP to be 3-4 MB ( may be ) at the end of project.

    What will happen

    • When user clicks and opens my site
    • XAP file will be downloade to the client
    • It will take time to download first time as I can understand it has big size.
    • Client works on my site and close the browser
    • After 2 days, again logs in.
    • WILL XAP file downloaded again or not ? Or Client will use from cache.

    I am expecting new release of my silverlight application at every three month after first release.

    • Now, I have released new version
    • Client comes again and logs in
    • Will XAP file be downloaded automatically again ? OR client will still see old XAP's SL content.

    Basically, I am not sure that silverlight is downloaded XAP file each time or only when it finds change ?

     

    Thanks in advance.

    Wednesday, June 18, 2008 10:16 PM
  • The caching of SL applications gets a bit annoying during development, I've got round it by using a generic handler:

    <%@ WebHandler Language="C#" Class="XAPHandler" %>

    using System;

    using System.Web;

    public class XAPHandler : IHttpHandler {

     

    public void ProcessRequest (HttpContext context) {

    context.Response.Expires = -1;

    context.Response.BufferOutput =
    false;

    context.Response.ContentType = "application/x-silverlight-app";

    context.Response.WriteFile(context.Server.MapPath("SLQuake.xap"));

    }

     

    public bool IsReusable {

    get {

    return false;

    }

    }

    }

     Then in my aspx pages, just change the Source attribute to the handler:

    <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/XAPHandler.ashx" MinimumVersion="2.0.30523" Width="800" Height="600" />

    I've used this for Flash development too, SWF files are cached just like XAP files and it causes the same set of headaches. Once the site is developed and deployed, just use the XAP file as normal (without the ashx handler)

    Tuesday, July 15, 2008 1:33 AM
  • A dumb solution that works (and thus my favorite Smile) is to simply change the name of the XAP file when deploying.

    Different name => invalidated cache 

    Still took me a while to come up with it. :-)

    Igor Ostrovsky

    Thursday, March 19, 2009 4:45 AM
  • protected void Page_Init(object sender, EventArgs e)
    {

    Silverlight1.Source = "Silverlight.xap?" + DateTime.Now.ToString("ssfff");

    }
    Wednesday, April 15, 2009 7:04 PM
  • The approach of changing XAP name on every deploy is good as well on proxy based internet connections (I got a client that had an "assesine" proxy... no matter what you deployed your XAP would remain cached for ours :-( ).

     I use the approach of adding a timestamp to the XAP names (to do that you need to change the XAP name in the Silverlight project properties, and on the web project: aspx OBJECT Tag, XAP File name).

     Cheers

       Braulio

    Saturday, November 14, 2009 4:27 PM
  • Here is the approach that I took and it worked quite well.  Like everyone else, I had a terrible time and many many hours wasted trying to see why my changes were not taking.  I did try changing the Assembly and File version numbers, and the GUID value for the project as well.  That did not work for me.  What finally worked, was the change my <object> tags from this:

    <object type="application/x-silverlight" height="611">
        <param name="source" value="/ClientBin/SilverApp.xap" />
        .....
    </object>

     and to something like this:

    <object type="application/x-silverlight" height="611">
        <param name="source" value="/ClientBin/SilverApp.xap?ignoreme=<%=System.DateTime.Now.ToUniversalTime()%>" />
        .....
    </object>

    Then it worked like a charm everytime.

    Brett

    Monday, November 23, 2009 9:51 PM
  • Yes... didn't remember the querystring trick , good point !

     Just only one thing, it could be a good idea to store a version value in the web.config and change on every deploy (to avoid not caching same XAP version on the client).

    Cheers

      Braulio

    Tuesday, November 24, 2009 1:43 AM
  • Presumably everyone here has the same objective concerning  production environment deployments - we want to cache the XAP until such time as we change it.. and when we do change it, we want the new XAP to be distributed first time it is loaded. 

    We don't want the client to waste time + bandwidth downloading a new identical XAP every time they vist our page. 

    What is the best way of achiving this?  It strikes me that setting content expiry headers in IIS or by code is not a great way as (depending on the setting), I may still get an old XAP or get force a download each time.

    Won't the ideas using a dynamic query string with the time in it suffer a similar problem?  depending on output caching, everytime time I hit the page presumably it will download the XAP all over again.

    Renaming the XAP itself seems perfect except a bit of a hassle.  Equally, we could rename a static query string  (rather than a dynamic time) inside the .ASPX page each time which seems less of a hassle but still a bit of a pain.  (e.g. "/ClientBin/SilverApp.xap?v1"  .. v2) etc

    Ideally IIS/HTTP would be clever enough to realise the file has changed and force-serve a new one. 

    More thoughts? 

     cheers

    ewart.

    www.fitnessmentor.net

     

     

    Personally I hate clearing my browser cache all the time! :)

    Monday, January 18, 2010 9:15 PM
  • 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.
    Monday, February 01, 2010 1:42 PM
  • Great and elegant solution !!

     Congrats jensen.

    Wednesday, June 16, 2010 2:51 AM
  • What about using the Version number in the query string as opposed to the datetime stamp.

    That way, only when it is a different version will a download be triggered (instead of all the time)?

    Wednesday, July 07, 2010 10:17 PM
  • You could do that if that's what you want. But do notice that my solution does not use the current datetime, so a new download will only be triggered when the XAP file has been written to. That the XAP file has been written to usually means that you have deployed a new version to the IIS.
    Thursday, July 08, 2010 4:45 AM
  • But how do you make the XAP files be stored in the cache in the first place?

    Wednesday, July 28, 2010 5:18 PM
  • Hi,

    I have another idea to use Web Application Assembly Version Number to use as tag to control the xap fresh download, but it has only one drawback that if used just deploy Xap then it will not work properly.

    I have found XAP modified date very much appealing.

    Furthermore is there any way to read SilverLight Project dll assembly version in asp.net? so that we can use that as a control tag?

    Thanks 

    Thursday, November 04, 2010 5:37 AM
  • You can try this. Replace the object tag in your aspx page with the following:

    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">        
            <%
                string orgSourceValue = @"ClientBin/Your.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);
             %>          
              <param name="onError" value="onSilverlightError" />
              <param name="background" value="white" />
              <param name="minRuntimeVersion" value="4.0.50401.0" />
              <param name="autoUpgrade" value="true" />
              <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0" style="text-decoration:none">
                   <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
              </a>
            </object>


    Append XAP created data to the value on the Source parameter,  this way when you have a new Version of XAP, the new XAP will get downloaded to replace the one in the cache.  

    Thursday, November 04, 2010 9:56 AM
  • perfect

    Thursday, November 18, 2010 6:02 AM
  • These solutions all require a windows server, what if you're running a LAMP set up? :)

    Cheers, Paul.

    Thursday, November 18, 2010 3:26 PM
  • the solution works great for the main xap file.

    But we're using prism and in firefox it sometimes happens that the modules we load in our shell are cached too and it seems I cannot use the same trick on the url of the module xaps, because I cannot change the way prism loads the xap from the server.

    anybody with the same issue?

    Monday, December 20, 2010 12:30 PM
  • Hello guys,

    Is there any update about this issue? I am still concerned about this. What if I changed the SL project assembly number? Would not this be considere a different assembly, consequently invalidating the client browser cache and the file would be downloaded?

    For me this seems not to work.... I think that downloading the xap file every time is not also a good way of managing this....

    Thank you,

    Igor.

    Monday, February 07, 2011 11:46 AM
  • Hello,

    But in my launcher XAP most of the dll respective to system, microsoft, telerik and our framework respective are common, which hardly change. It is one time download on client side is enough for me.

    But I want that only other dll like my control library, XAP respective process dll which I want to download, when ever any change instead of all dll, which hardly will change.

    How we can acheive this?

    Regards,

    Sandeep

    Saturday, February 19, 2011 10:12 PM
  • You could use MEF in order to achieve that:

     - You download your DLL the first time store it cached in isolated storage (you could add a timestamp or check the version).

     - Then whenever you start the app you make an asynchronous call to check if there is a newer version of the DLL, in that case grab the DLL from the remote location.

    On the other hand, how often do you make that changes? If you use the version trick parameter in the query string you will download your XAP only when you make a new deployment.

    Sunday, February 20, 2011 2:34 AM
  • This is quite a serious issue for us.  We also have more than one xap file since the application is spread over multiple xap files.  Any tricks to modify the object tag or other to make sure the initial xap file is correct is only a small part of the solution for us.

    The basic requirement is the same as mentioned above - cache as much as possible if the server side copy has not changed, but download immediately after any changes.

    Content expiry is only partially solving the problem since the content can only expiry immediately, which means a download every time, or expire after a set period, which means any updates can be skipped for a while.

    I've tried to read up on the use of ETags in IIS7 & 7.5 but have not found enough info yet.  This seems to be an expiry tag that the server updates when the content updates.  Has any tried this with Silverlight with any success.

    The answer seems to lie in the fact that the server has to dictate when content expires and not the client or client cache (as with expiries).

    ETags anyone?


    Monday, February 28, 2011 4:17 PM
  • The only reasonable solution to these problems is to report incorrect caching behavior to the browser creators.

    Monday, February 28, 2011 5:41 PM
  • Which framework are you using for the XAP partitioning? 

    If it's custom or Prism you can add your own module and in the http call to download the XAP just use as param in the query string the version (you could try to get that value from the XAP, or setup a XAP version numbers xml file and store it in the isolated storage).

    Another better option is, instead of relying on the browser to provide you the cached XAP's rely on the isolated storage to do that, there are as well implementations of this kind of caching, but you have to be aware if the app is not OOB by default you only have 2 Mb caching.

    HTH 

     Braulio

    Tuesday, March 01, 2011 2:09 AM
  • Hi

    I want a Solution to load the updated XAP by browser from cache without using ".xap?version" query string method as it throws some exception to my context. 

     

     

     

    Monday, March 28, 2011 9:47 AM
  • I have found that changing my IE settings to use "Every Visit to the Page" makes it update.

    This should not be necessary of course.

    Monday, April 18, 2011 4:40 PM
  • <object id="Xaml" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
    <%
    string xapSrc = @"ClientBin/MySlApp.xap";
    string param;
    if (System.Diagnostics.Debugger.IsAttached)
    param = "<param name=\"source\" value=\"" + xapSrc + "\" />";
    else
    {
    string xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + xapSrc;
    DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
    param = "<param name=\"source\" value=\"" + xapSrc + "?ignore="+ xapCreationDate.ToString() + "\" />";
    }
    Response.Write(param);
    %>

    You can try with this code in your server side page.  Its downloading xaps with every new deployment.

    <object id="Xaml" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">

    <%

    string xapSrc = @"ClientBin/MySlApp.xap";

    string param;


    if (System.Diagnostics.Debugger.IsAttached)

    param = "<param name=\"source\" value=\"" + xapSrc + "\" />";

    else

    {

    string xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + xapSrc;

    DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);

    param = "<param name=\"source\" value=\"" + xapSrc + "?ignore="+ xapCreationDate.ToString() + "\" />";

    }

    Response.Write(param);

    %>


    Thursday, April 21, 2011 3:58 AM
  • hi all,
    as per one of the above post I enabled  Content Expiration HTTP header option on for XAP file by checking "Expire Immediately" radio button.
    but with this setting it never caches XAP & downloads every time from sever when I refresh page.
    I need to download xap from server only if it newer than xap in cache.

    can we acheive this by setting any property in IIS?

    regards,
    -Shwetank

    Wednesday, August 24, 2011 3:34 AM
  • I am also facing this issue and would appreciate a transparent and complete solution.

    Thursday, September 01, 2011 9:24 AM
  • Add following lines of code in web.config file

    <configuration>

    <system.webServer>

        <caching>

          <profiles>

            <add extension=".xap" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange"/>

          </profiles>

        </caching>

      </system.webServer>

    </configuration>

    Tuesday, October 04, 2011 12:05 PM
  • Have not read the whole thread, but simply changing the value for 'cachepreventer'
    is doing the job very well for me :

    ....

    <div id="silverlightControlHost" >

    <object id="siliobj" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
    <param name="source" value="ClientBin/zoomBase.xap?cachepreventer=2011.09.20_22"/>
    ....

    Thursday, October 06, 2011 4:25 AM
  • Good job, this worked perfect for our needs of only wanting to make them reload it when we updated our xap. We added the version to the end of the xap name. This is not a dumb solution : D

    Thanks IgorO!

    Brandon

    Monday, April 30, 2012 5:55 PM
  • Well the .xap file gets downloaded on every page refresh ... in my case the zap file is 7.5mb. huge performance issue, the browser caches the file for a reason ... the solution should be browser should get the new file only after the deployment.

    Krish

    Thursday, February 21, 2013 11:23 PM