This is part 2 of 2 from the article series 'Silverlight in the Azure cloud'.
Read part 1
In the first part of this series, we looked at how we could move a Silverlight application to Windows Azure. The biggest conclusion there was that from a Silverlight point-of-view, not much work was required. The Silverlight application itself – the XAP file – is in this case packaged along when publishing the web role in which the Silverlight application resides.
The database was moved to SQL Azure, a SQL Server in the cloud, hosted as a service and therefore benefitting from high availability and scalability. Next to the database, the services (in our case, a WCF service) were moved to the cloud as well. The Silverlight application talked to the services hosted in the cloud. We just had to change the address of the service in the configuration to be up and running again.
In this second part, we’ll take a look at some more advanced stuff. We’ll start by looking at how we should work if the Silverlight application is using RIA Services for its data needs. Next, we’ll look at how we can work with Azure storage from Silverlight. We’ll finish off by looking at the combination Windows Phone 7/Azure. A lot of ground to cover so let’s get to it!
The demos for this second part can be found here.
RIA Services in the cloud
When we look at a typical RIA services application, there’s a clear link between the client and the server project, both when the services are hosted in a site and when we use a separate RIA services class library. This link can be seen in the fact that within the Silverlight application, code gets generated based on the code in the RIA services classes. Also, the client project has a link to the server project.
RIA Services require in the web project that there are a few assemblies available. When we add a RIA service to a project, automatically, Visual Studio creates references to:
- System.ServiceModel.DomainServices.EntityFramework
- System.ServiceModel.DomainServices.Hosting
- System.ServiceModel.DomainServices.Server
- System.ComponentModel.DataAnnotations
The screenshot below shows these references in the web project. Note that if you are building a RIA services library, these assemblies are added in the server-side project as well.
When we are deploying to Azure, we are actually deploying to a virtual machine running Windows 2008. There’s an IIS running as well that hosts your web application. However, this machine doesn’t have the RIA services assemblies installed (they are not in the GAC, since there’s no installer that put them there). Therefore, when we deploy an application that consumes RIA services, we need to make sure these assemblies will be packaged into the package we’ll deploy.
In the sample application, this is solved by setting the 3 System.ServiceModel.DomainServices assemblies to Copy local à True. This makes sure that these assemblies aren’t referenced from the GAC (like on our local development machine), but instead are referenced from the local bin directory.
You can easily see if you did this correctly by looking at the size of the package that gets created when publishing. In the sample case, when the assemblies are correctly included, the size of the package is almost 9MB. When setting the copy local to False, this was only 7.5MB.
Apart from this change, RIA services applications work perfectly in Windows Azure. There’s no need to perform any configuration changes.
Blob storage and Silverlight
Azure storage provides scalable storage for your files. Actually, Azure storage consists out of three parts: Blob Storage, Table Storage and Queue Storage. Blob Storage can be used to store binary and textual files/data in the Azure cloud. Each file that gets added to the cloud gets replicated and therefore is safely stored with an almost non-existent chance of losing the file. Finally, queue storage is capable of storing messages and can be used for example to have a web role and a worker role to communicate with each other.
While all of these are usable from a Silverlight client application, I’ll focus on blob storage, since that seems the one I have used most for clients from a Silverlight perspective. If you want to use table or queue storage, take a look at their REST API. Note that blob storage also has a REST API but I won’t be using that here.
Instead, I want to securely store files in blob storage and retrieve them from a Silverlight application. To store files, we first have to create a storage account via the Azure portal, as shown in the screenshot below. Each Windows Azure account can have multiple storage accounts, each storage account can have up to 100TB of data!
Once created, a URL gets created for this storage account (for all 3 services), as shown in the portal screenshot below.
The portal does not give you the ability to upload files. Instead, you need a tool such as CloudBerry or Cloud Explorer. The screenshot below shows Cloud Explorer on my storage account, where I have a few containers created. A container can be compared to a folder; it can contain other containers or files.
Per container, we can specify the access permissions. A file can be publicly accessible or private. The files in this case are going to be used inside of a public Silverlight application so the container gets Full public read access. If you want to store files that users have to pay for, you could use private access and used Shared Access Signatures to allow users to access files with a public key token.
The files are now accessible via a URL, shown below.
We can now use this URL inside of a Silverlight application. Files such as a video or an image work in the same way. In the code below, we are using the file stored in blob storage as the source of a MediaElement.
<Grid x:Name="LayoutRoot">
<MediaElement Width="300" Height="200" Stretch="Uniform"
Source="http://gillcleeren.blob.core.windows.net/test/Butterfly.wmv"
AutoPlay="True"></MediaElement>
</Grid>
Reading an XML stored in blob storage
If we store XML files in Azure storage and want to read out these files from a Silverlight application, we will come across cross domain restrictions. The Silverlight application is running from our domain, while the XML we want to read out is stored in blob storage. The solution is quite simple though: we need to place a clientaccesspolicy.xml in the root container.
However, the root container out-of-the box can only contain other containers, not files. The solution is creating a container named $root. This $root is a special container that points back to the root. Inside this container, we can place the clientaccesspolicy.xml file as shown below.
From Silverlight, the file can be read out as follows, using the direct link to the XML in blob storage:
private void LoadTrendingTopics()
{
WebClient client = new WebClient();
client.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://gillcleeren.blob.core.windows.net/test/trendingtopics.xml",
UriKind.Absolute));
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
XDocument document = XDocument.Parse(e.Result);
List<Trend> twitterData = (from status in document.Descendants("trend")
select new Trend
{
TrendingTopic = status.Value,
Url = status.LastAttribute.Value
}).ToList();
TrendingTopicListBox.ItemsSource = twitterData;
}
else
{
MessageBox.Show(e.Error.ToString());
}
}
XAP in Azure storage
In part 1, I concluded by mentioning that we can’t just update the XAP file when hosted in a hosted service, because an update basically comes down to upgrading the instance to a new version. A solution for this problem is placing the XAP file in blob storage. The following steps need to be done to do so.
Step 1: Create a container for the XAP file
While not really necessary, I advise to use a container specific for the XAP file.
Step 2: Place the XAP file in blob storage
After letting Visual Studio create the XAP file, copy the XAP file using Cloud Explorer to the blob storage.
Step 3: Update the URL in your ASPX
In the web project, update the URL of the source parameter, like below.
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2,"
type="application/x-silverlight-2"
width="100%" height="100%">
<param name="source"
value="http://gillcleeren.blob.core.windows.net/xap/RemoteXap.xap" />
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50826.0" />
Step 4: Publish the hosting site in a web role to Azure
We can now go ahead and publish the site to Azure, with the XAP being referenced from blob storage.
Using this approach, we can easily update the XAP site while not having to republish the site.
Windows Phone and Azure
The final topic I want to discuss here is Windows Phone and Azure. Many applications for Windows Phone use some kind of service layer to talk to a database backend. If we host these services in Azure, Windows Phone can perfectly access these services as well. There’s no real difference since we use Silverlight as the development platform.
Azure can be very interesting in a WP7 scenario. The cloud is always available, while Windows Phone apps don’t always have a network connection available. Occasionally connected applications can locally store files and upload to the cloud when a connection is available.
Summary
This concludes our mini-series on Windows Phone and Azure. In this second part, we looked at some practical implementations, including RIA Services, Windows Phone and blob storage.
About Gill
Gill Cleeren is Microsoft Regional Director (www.theregion.com), Silverlight MVP (former ASP.NET MVP), INETA speaker bureau member and Silverlight Insider. He lives in Belgium where he works as .NET architect at Ordina. Passionate about .NET, he’s always playing with the newest bits. In his role as Regional Director, Gill has given many sessions, webcasts and trainings on new as well as existing technologies, such as Silverlight, ASP.NET and WPF at conferences including TechEd Berlin 2010, TechDays Belgium, DevDays NL, NDC Oslo Norway, SQL Server Saturday Switserland, Spring Conference UK, Silverlight Roadshow in Sweden… He’s also the author of many articles in various developer magazines and for SilverlightShow.net. He organizes the yearly Community Day event in Belgium.
He also leads Visug (www.visug.be), the largest .NET user group in Belgium. Gill recently published his first book: “Silverlight 4 Data and Services Cookbook” (Packt Publishing). You can find his blog at www.snowball.be.
Twitter: @gillcleeren