Thursday 25 February 2010

Automatically download the latest XAP file

You can find yourself in situation that you want to the client browser automatically download latest .XAP file from ClientBin. It's useful for example, if you regularly changing versions and the client's browser ignores these changes. I figured out that this issue is typical to Google Chrome browser but it can occurs with other browser too.

The silverlight xap is loaded by the browser just like any other server resource, so what you are seeing is the cache keeping the old xap and not refreshing with the new one.
To fix this issue, so "tell" the client's browser to automatically download the latest version of XAP file, there are 2 methods.


One approach you could look at is to use a handler to deliver the XAP file
Using the Xap Handler on the server (asp.net) you can add headers to the request from the browser to instruct it not to cache the xap file - you could add more logic to that so these headers are only added when you want to have the xap refreshed, perhaps based on a value in a config file.
Open your Silverlight application in Visual Studio. Add new Generic Handler file (.ashx) to your web application, name it e.g. "SilverlightHandler.ashx" - place the file to the web root, where your *.aspx files are.

Modify the created handler to look like this one:

<%@ WebHandler Language="VB" Class="SilverlightHandler" %>

Imports System
Imports System.Web

Public Class SilverlightHandler : Implements IHttpHandler

Public Sub ProcessRequest(ByVal context As HttpContext) Implements _
IHttpHandler.ProcessRequest
With context.Response
.Expires = -1000
.BufferOutput = False
.ContentType = "application/x-silverlight-app"
.WriteFile(context.Server.MapPath("ClientBin\SilverlightApp.xap"))
End With
End Sub

Public ReadOnly Property IsReusable() As Boolean Implements _
IHttpHandler.IsReusable
Get
Return False
End Get
End Property

End Class

Note: please change the name of your Silverlight application XAP file, in this case replace SilverlightApp.xap

Then change your Silverlight asp.net control's or object's tag Source value to point to "SilverlightHandler.ashx"
For example your control could look like this:
<object data="data:application/x-silverlight-2,"
type="application/x-silverlight-2" width="100%" height="100%">

<param name="source" value="SilverlightHandler.ashx" />
<param name="onError" value="onSilverlightError" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
</object>
Rebuild your Silverlight application - and that's all.

If you're using a WCF Service with your Silverlight application it can be essential to disable "Reduce XAP size by using application library caching" Silverlight build option.
To do this, in the Solution Explorer right click on your Silverlight application project and select Properties. On the first tab, named "Silverlight", make sure that the "Reduce XAP size by using application library caching" option is unchecked. Save changes and rebuild your application. Now, it should work correctly.


Using this technique will force the client's browser automatically download the latest XAP file. Right now, if you take a tour to your "Internet Temporary Files" folder, you can find, that SilverlightApplication.xap is no longer downloaded, it's replaced by the SilverlightHandler.ashx file which takes care about XAP file handling.

Another approach is when you don't want to change the code

If you don't want to use the xaphandler, a simpler way is to just rename the xap file and then update the Silverlight object tag (or silverlight asp.net control) to point to the new one. The browser will then download this automitically. The page url the silverlight control is hosted in will not have changed so the users will not have to change anything.

If you choose first or second scenario it should solve the browser's caching.

2 comments:

Skot said...

Perfect - thanks for this!

Anonymous said...

How to force silverlight application to re-download if new verson is available on server to prevent any operation on old application by any User.

Understand the following scenario : I have my silverlight application up & running on hosted server and there are approx 500 user who are using it same time with application version around 192.3XXXX.

Later on I have developed some crucial business functionality and released application on server with version around 192.4XXXX. Next day all 500 user are working on application version 192.4XXXX. and on same day I found that I have made some serious mistake & I have to fix it as soon as possible. so i have applied the fix and released the Application on server with version around 192.5XXXX.

Now here come my Question. How can i enforce this 500 user to use 192.5XXXX at same time. I can not tell each user to reload the app and some of may misuse the application's functionality (as earlier mention, some serious mistake i made in code like showing confrontational data on some form etc. )

Any suggestion or idea to overcome such situation. Or something like that i can manege from server to force client reload app and download new version.

Thx in advance.