Silverlight in the Mesh and the “Cloud” – Hosted Service and Blob Storage (Part 2)
Hello. As I promised here I’m starting to describe my experiences in creating Silverlight Mesh Enabled Web Application (MEWA or SMEWA) with Cloud Hosted Services and Cloud Storage.
Today I’ll talk about creating the storage and supported hosted services.
First of all I needed to be a part of Windows Azure CTP and have at least 1 Storage account (to have persistent and non-persistent storage in Windows Azure) and at least 1 Hosted Services account (environment that provides the hosting and management service for cloud based applications).
To get such account(s) one should apply for them via Microsoft Connect site.
After getting invitation to this program from Microsoft Connect you could go to Azure Services Developer Portal, claim received tokens, download and install Windows Azure SDK and Windows Azure Tools Visual Studio and start creating cloud based applications. One small note here – those tools doesn’t support Windows 7 Beta right now, so it will not work there.
Once all setup done, we could go to Azure Services Developer Portal and create a new project:
I created 1 for Storage

(Endpoints are gateways that I could use from anywhere when accessing my storage account, and pair of key access is to secure my connection.)
Another project was created for Hosted Services
You could have 2 projects simultaneously running at the cloud – one for testing/debugging online and one as a real production service. The URL for the service in Staging will change every time you will re-deploy the new version of the service, thus you have to reconfigure your applications which will work with those services externally.

Now back to my “Cloud Store”. I decided to provide access to my cloud storage via Web Services and those web services will be in my Host Services Project.
After installing Windows Azure Tools for Visual Studio you will get new project templates:
For my purposes I’ve created Web Cloud Service. In my service I’ve added 2 new web services – one which will be used by Content Management UI SMEWA, and one by Content Consumer UI SMEWA. I wish I had more Hosted Services projects allocated to use different projects for each application, but I haven’t. Also, I could use the same service for both applications but I wanted the whole thing to me close to the real world architecture.
When you creating such a project Visual Studio will create 2 projects in the solution – ASP.NET Web Application and the Web Cloud Service Project:

In my case I’ve also added 2 exiting projects from Windows Azure SDK Samples (Common and Storage Client) which will handle for me all communications with the blob.
Now to the interesting part. Lets see how to work with the blob storage. Most of the “real mesh code” was taken from PCD demos and samples from Windows Azure SDK so if you need more info you know where to find it.
Let’s see the FileUpload WebMethod as an example:
[WebMethod]
public bool UploadFile(string fileName, string contentType ,byte[] f)
{
//Assume success - its good to be optmistic :)
bool bRes = true;
try
{
// Get the configuration from the cscfg(cloud service configuration) file
StorageAccountInfo accountInfo = StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration();
// Container names have the same restrictions as DNS names
BlobStorage blobStorage = BlobStorage.Create(accountInfo);
_Container = blobStorage.GetBlobContainer(RoleManager.GetConfigurationSetting("ContainerName"));
// returns false if the container already exists, ignore for now
// Make the container public so that we can hit the URLs from the web
_Container.CreateContainer(new NameValueCollection(), ContainerAccessControl.Public);
BlobProperties properties = new BlobProperties(Guid.NewGuid().ToString());
// Create metadata to be associated with the blob
NameValueCollection metadata = new NameValueCollection();
metadata["FileName"] = fileName;
properties.Metadata = metadata;
properties.ContentType = contentType;
// Create the blob
BlobContents fileBlob = new BlobContents(f);
_Container.CreateBlob(properties, fileBlob, true);
}
catch (WebException webExcept)
{
bRes = false;
if (webExcept.Status == WebExceptionStatus.ConnectFailure)
System.Diagnostics.Debug.WriteLine("Failed to connect to the Blob Storage Service, make sure it is running: " + webExcept.Message);
else
System.Diagnostics.Debug.WriteLine("Error creating container: " + webExcept.Message);
}
catch (Exception ex)
{
bRes = false;
System.Diagnostics.Debug.WriteLine(ex.Message);
}
return bRes;
}
The code itself is pretty easy – create or get blob container, fill new blob properties and metadata and the create new blob to the container.
Same goes for DeleteFile WebMethod
[WebMethod]
public bool DeleteFile(string fileName)
{
bool bRes = true;
// Get the configuration from the cscfg file
StorageAccountInfo accountInfo = StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration();
// Container names have the same restrictions as DNS names
BlobStorage blobStorage = BlobStorage.Create(accountInfo);
_Container = blobStorage.GetBlobContainer(RoleManager.GetConfigurationSetting("ContainerName"));
//Check if desired blob exists, and if it does - delete it
if (_Container.DoesBlobExist(fileName))
bRes = _Container.DeleteBlob(fileName);
return bRes;
}
Last, but not least is I want to able to show blob contents in my management SMEWA, so I created GetFiles WebMethod
[WebMethod]
public List<ContentEntry> GetFiles()
{
// Get the configuration from the cscfg file
StorageAccountInfo accountInfo = StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration();
// Container names have the same restrictions as DNS names
BlobStorage blobStorage = BlobStorage.Create(accountInfo);
_Container = blobStorage.GetBlobContainer(RoleManager.GetConfigurationSetting("ContainerName"));
//Get blobs in my account
IEnumerable<object> blobs = _Container.ListBlobs(string.Empty, false);
List<ContentEntry> filesList = new List<ContentEntry>();
foreach (object o in blobs)
{
BlobProperties bp = o as BlobProperties;
if (bp != null)
{
//Get current blob properties
BlobProperties p = _Container.GetBlobProperties(bp.Name);
NameValueCollection fileEntryProperties = p.Metadata;
//Create data container which will return relevan information to the client
filesList.Add(new ContentEntry() { BlobName = p.Name, FileUri = bp.Uri.ToString(), FileName = fileEntryProperties["FileName"], Submitter = "ALEX" });
}
}
return filesList;
}
The ContentEntry class itself is pretty simple also:
public class ContentEntry
{
public ContentEntry()
{
}
public ContentEntry(string blobName, string fileAddress, string name, string user)
{
BlobName = blobName;
FileUri = fileAddress;
FileName = name;
Submitter = user;
}
public string FileUri { get; set; }
public string BlobName { get; set; }
public string FileName { get; set; }
public string Submitter { get; set; }
}
After doing all that, I had to configure my service to work with local development storage. Configuration settings for cloud services defined in file named “ServiceDefinition.csdef”. In my case it is like follows:
<ServiceDefinition name="StoreBusinessTier" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole">
<InputEndpoints>
<!-- Must use port 80 for http and port 443 for https when running in the cloud -->
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</InputEndpoints>
<ConfigurationSettings>
<Setting name="AccountName"/>
<Setting name="AccountSharedKey"/>
<Setting name="BlobStorageEndpoint"/>
<Setting name="ContainerName"/>
</ConfigurationSettings>
</WebRole>
</ServiceDefinition>
And the actual values for those configuration settings are in “ServiceConfiguration.cscfg” file:
<ServiceConfiguration serviceName="StoreBusinessTier" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
<Role name="WebRole">
<Instances count="1"/>
<ConfigurationSettings>
<!--Local Develoment Storage Account Settings-->
<Setting name="AccountName" value="devstoreaccount1"/>
<Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
<Setting name="BlobStorageEndpoint" value="http://127.0.0.1:10000/"/>
<!--Real Cloud Storage Settings-->
<!--<Setting name="AccountName" value="STORAGE_PROJECT_NAME"/>
<Setting name="AccountSharedKey" value="PRIMARY_ACCESS_KEY"/>
<Setting name="BlobStorageEndpoint" value="https://blob.core.windows.net"/>-->
<Setting name="ContainerName" value="files"/>
</ConfigurationSettings>
</Role>
</ServiceConfiguration>
Compiling an executing the application will bring Developer Storage
and the Development Fabric

and finally IE with standard ASP.NET Web Application debugging experience. In my case the WebService was a start-up file, so I’ve got this:
My second web service has pretty simple functionality – Listing the exiting files and getting the specific file content:
GetFile WebMethod should return me the list of files (like FileHandler web service) – I thought I could even use the one from FileHandler… I thought so, but it will not work – will see why in last part.
GetFile WebMethod should return me the contents of the selected file (byes[] or Stream or something) – pretty easy task… Hm… This one was actually not trivial as it turns out – will see why also in last part.
Last thing I did after checking this service locally with some tester application I’ve deployed this service to the cloud and started to work on my SMEWA:
Stay tuned for the next part.
This part will connect the two worlds which are very close, but somehow not connected until now - I will show how to create management SMEWA and use Azure Storage (blob) and Azure Hosted Services (I just created here) to save the data from Live Mesh Application to the Windows Azure Storage.
Enjoy,
Alex