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
 

Getting Build Date and Time from Assembly Version

Filed under: .NET,Silverlight — fmuntean @ 10:43 pm

When you use the following format for Assembly Version Attribute 
[assembly: AssemblyVersion(“1.0.*”)] the build number and revision are automatically generated for you when building the application.

It turns out that that a formula based on DateTime.Now is used to generate those numbers.

So to get the DateTime time stamp when the assembly was build all you have to do is:

Code Snippet
  1. Version v = ParseVersionNumber(Assembly.GetExecutingAssembly());
  2.            return new DateTime((v.Build – 1) * TimeSpan.TicksPerDay + v.Revision * TimeSpan.TicksPerSecond * 2).AddYears(1999);