In The Mix

As a SharePoint architect I have the business behind me and the Developers and IT Pro on my shoulders.

Correctly Handling the Silverlight OOB Update when hosted inside WCF December 28, 2010

Filed under: Silverlight — fmuntean @ 10:54 pm

On a project that I was working on lately I had to use Silverlight OOB (Out Of the Browser) and the xap file was actually not hosted in IIS but rather in a custom application (read either console app or Windows Services for the scope of this post).

The architectural approach is:

image

On the server side we have a console application running that host a WCF REST Service which will deliver, using WebGet, the files needed to run the Silverlight application. In other words the WCF service takes the place of IIS.

This is so that the user easily go to a web page then install the Silverlight application locally.

Now let’s see the implementation for this approach:

First the Service interface:

  1. [ServiceContract]
  2.     public interface ISilverlightHost
  3.     {
  4.         [OperationContract]
  5.         [WebGet(UriTemplate = “”)]
  6.         Stream GetHtml();
  7.  
  8.         [OperationContract]
  9.         [WebGet(UriTemplate = “clientaccesspolicy.xml”)]
  10.         Stream GetPolicy();
  11.  
  12.         [OperationContract]
  13.         [WebGet(UriTemplate = “SLPlayer.xap”)]
  14.         Stream GetXap();
  15.  
  16.         [OperationContract]
  17.         [WebGet(UriTemplate = “Silverlight.js”)]
  18.         Stream GetJavaScript();
  19.  
  20.     }

And the implementation:

  1. public class SLService : ISilverlightHost
  2. {
  3.     public Stream GetHtml()
  4.     {
  5.         return new FileStream(“SLPlayer.html”, FileMode.Open, FileAccess.Read);
  6.     }
  7.  
  8.     public Stream GetJavaScript()
  9.     {
  10.         return new FileStream(“Silverlight.js”, FileMode.Open, FileAccess.Read);
  11.     }
  12.  
  13.     public Stream GetXap()
  14.     {
  15.         var request = WebOperationContext.Current.IncomingRequest;
  16.         var response = WebOperationContext.Current.OutgoingResponse;
  17.  
  18.         //we need to manually implement a way to correctly update the xap file when running OOB
  19.         DateTime? modifiedSince = request.IfModifiedSince;
  20.         if (modifiedSince!=null)
  21.         {
  22.             var fileInfo = new FileInfo(“SLPlayer.xap”);
  23.             if (fileInfo.LastWriteTime < modifiedSince)
  24.             {
  25.                 response.StatusCode = HttpStatusCode.NotModified;
  26.                 return null;
  27.             }
  28.         }
  29.         response.ContentType = “application/x-silverlight”;
  30.         return new FileStream(“SLPlayer.xap”, FileMode.Open, FileAccess.Read);
  31.     }
  32.  
  33.     public Stream GetPolicy()
  34.     {
  35.         SetResponseContentType(“text/xml”);
  36.         return new FileStream(“clientaccesspolicy.xml”, FileMode.Open, FileAccess.Read);
  37.     }
  38.  
  39.     private static void SetResponseContentType(string contentType)
  40.     {
  41.         if (WebOperationContext.Current != null)
  42.         {
  43.             WebOperationContext.Current.OutgoingResponse.ContentType = contentType;
  44.         }
  45.     }
  46. }

 

Now lets explain the code a little bit:

1. The user open the web url for this application using a web browser the WCF will intercept the request and get return the html file stored locally see GetHtml method.

2. The browser parse the html and loads the Silverlight.js and the xap file.

3. The clientaccesspolicy.xml is provided in case there are other WCF services hosted under this url.

Now let’s talk about the OOB update of the application:

The process of upgrading a Silverlight application is described here:

Silverlight 3 Out-of-browser Update Model by Tim Heuer (the same applies for Silverlight 4 in case you are wondering)

As described in Tim’s post the Silverlight PlugIn send a request to the original web location of the Silverlight application using a special header, If-Modified-Since which IIS interprets it and respond correctly to it. However our WCF service will not know what to do with it by default so it is up to us to correctly handle this (see GetXap method).

The main idea here is that each time when the Silverlight app is either installed or upgraded some metadata is stored locally including a timestamp of the last update. when calling  Application.Current.CheckAndDownloadUpdateAsync(); the plugin will check if the file was modified after the last time stamp and the expectation is that the server will respond with a status code of 304 Not Modified and an empty body when there was no update. However when the file is newer then  regular response is expected including the xap file and a status code of 200 OK.

There were plenty of posts out there explaining how to host Silverlight inside WCF but none talked about the issue with the update. Hope this post will be helpful to people who will wonder why their application always reports update available even when there is none.

Advertisements
 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s