Windows Azure Storage Client Library for Windows Runtime

We are excited to be releasing two libraries for Windows 8 and Windows Server 2012 as Community Technology Preview (CTP) that fully support the Windows Runtime platform. These libraries can be used to build Windows Store applications on both ARM and X86 in any of the supported languages (JavaScript, C++, C#, and VB). We have invested a large amount of effort into ensuring Windows developers can easily leverage Windows Azure Storage in an easy and consistent manner via the language of their choice. This blog post serves as an overview of these libraries and highlights a few key differences when developing for Windows Runtime.

To download the Storage Client libraries for Windows 8 click here. (UPDATED)

Tables

The Windows Runtime component contains a new lightweight table service implementation based on OdataLib. One key departure from the desktop client library is this release does not contain a table implementation based on DataServiceContext (System.Data.Services.Client.dll) as this is not projectable to the various languages Windows Runtime supports. To support JavaScript in the base library the table implementation that ships in the core component is limited to a single IDictionary based entity type (DynamicTableEntity) for persisting and querying entities. For languages other than JavaScript we have released a table extension library (Microsoft.WindowsAzure.Storage.Table.dll) that provides support for strong entity types (POCOs), generic queries, reflection based serialization, and the EntityResolver. This assembly is consumable by C++, C#, and VB applications. (Note: For c# developers, the current release does not currently expose an IQueryable implementation to allow users to create queries via LINQ similar to the legacy 1.x storage clients. As an alternative lightweight helpers are provided via static methods on the TableQuery class to assist in the construction of query strings.) 

Key differences between Windows Runtime and the .NET 4.0 library

The Windows Runtime library shares some common code with the .NET equivalent; however there are some key differences necessary to fully support the Windows Runtime platform. These differences are discussed below.

Windows Runtime Types

The Windows Runtime public API only exposes Windows Runtime types which are consumable by all supported languages including JavaScript. If you are migrating an application from the .NET client you will need to use the Windows Runtime equivalent types. .NET 4.5 exposes some helpful extension methods to convert between .NET types and Windows Runtime types, for example System.IO.Stream.As[Input|Output]Stream() and Windows.Foundation.IAsync[Action|Operation].AsTask().

Additionally, due to the restrictions for Windows Runtime components, all protocol layer constructs can no longer be exposed. As such, the .Net protocol layer implementation is not available when developing Windows Runtime applications.

Async / Await Pattern

The Windows Runtime library utilizes the Async / Await pattern and does not expose any synchronous methods or APM equivalents. This is in keeping with best practice for developing modern Windows Runtime applications. The APIs exposed in the library are bound by the network and connectivity, as such leveraging this pattern is essential in keeping your applications fast and fluid. For .NET developers that may wish to use the Task Parallel Library (TPL), you may use the extension methods mentioned above to convert the exposed IAsyncActions and IAsyncOperations to Task objects.

Cancellation

All APIs support cancellation via the IAsyncInfo.Cancel() method. To leverage cancellation tokens in .NET you may either create a Task object via the extension methods provided as shown below:

 CancellationToken myToken = new CancellationToken();
Task<bool> createTask = myTable.CreateAsync().AsTask(myToken);

Or you may hookup your CancellationToken via CancellationToken.Register():

 CancellationToken myToken = new CancellationToken();
IAsyncOperation<bool> createOperation = myTable.CreateAsync();
myToken.Register(createOperation.Cancel);
Exceptions

Windows Runtime components cannot expose strong typed exception objects; instead a Windows Runtime application must rely on the HResult of the exception that it receives. (Note: There are some instances where the exception message is populated; however developers are encouraged not to depend on this as it is not available in all situations.) To simplify this paradigm for our users we have provided an optional feature available via OperationConext that allows users to still retrieve rich exception information in plain POJO object. By calling an overload and passing in an OperationContext object clients can analyze status and exception information in a language agnostic way.

Here is an example of how to retrieve additional exception information via the OperationContext:

 // You will need the following usings
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob
…

// Create the BlobClient from the CloudStorageAccount
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

// Get a reference to a container that does not exist
CloudBlobContainer container = blobClient.GetContainerReference("containerthatdoesntexist");

// Create an OperationContext to track the request
OperationContext deleteContainerContext = new OperationContext();
int? exceptionResult = null;

try
{
    // This will generate a resource not found exception
    await container.DeleteAsync(null /* AccessCondition */, null /* BlobRequestOptions */, deleteContainerContext);
}
catch (Exception e)
{
    exceptionResult = e.HResult;
}

if (exceptionResult.HasValue)
{
    // Display a detailed error to the user. Alternatively, you could inspect the extended error information returned by the server to provide some recover logic here. 
    MessageDialog errorDialog = new MessageDialog(string.Format("{0} : {1}", deleteContainerContext.LastResult.HttpStatusMessage, deleteContainerContext.LastResult.ServiceRequestID));
    await errorDialog.ShowAsync();
}

This sample will result in the following error being displayed to the user:

close

Authentication

A key feature that Windows Azure Storage provides is fine grained Shared Access Signature permissions that allow users to write mobile and distributed applications that directly interact with their storage in a controlled manner without exposing their private key information. For example, as a mobile game developer I can design my client application to directly query a user’s achievements from a given table, but limit the user to read access over a strict PartitionKey / RowKey range. Additionally, I can enable Logging on my storage account to monitor usage and behavior of my applications. By alleviating the need to provide a middle tier service I can not only provide lower latencies for the client application, but also dramatically reduce cost. For more information regarding Shared Access Signatures, please see this blog post.

The StorageCredentials object supports Anonymous, Shared Access Signature, and Account and Key via the SharedKey and SharedKeyLite authentication schemes. When developing mobile applications that leverage Windows Azure Storage there are a few best practices that should be followed which are detailed below

  • Support for Account and Key is included in the library for completeness and to support scenarios where an application user may provide their own credentials (for example a storage explorer application). However, users should never distribute account and key information as part of a mobile application as it is no longer under their control. If a key is inadvertently leaked you can rotate your storage keys via the Windows Azure Portal.
  • It is considered best practice to utilize Shared Access Signature authentication in a mobile application. Shared Access Signatures should be tied to an Access Policy on the Container, Table, or Queue which will allow them to be revoked in the case they are abused or leaked.
  • The Windows Push Notification service can be used to distribute Shared Access Signature tokens to all application users or a given subset. This provides a convenient mechanism to update tokens in the event of a compromised token.
  • When using Shared Access Signatures outside a secured network HTTPS should be used to avoid leaking the Shared Access Signature token.
  • When designing your application keep in mind that a given Container, Table, or Queue can support 5 Shared Access Policies (Signed Identifiers) which may dictate the granularity of permissions that you can issue via SAS.

Known Issues

Because of the differences in escaped character handling in Uris, using some special characters in blob names might cause authentication failures. These characters are listed below:

[ ] \

In the previous versions of Storage Client Library, backslash (‘\’) was converted to forward-slash (‘/’) automatically. Hence, if you were using backslash, please replace it with a forward-slash to work around the issue, since the current client library no longer automatically does that conversion.

Similarly, [ and ] characters cause authentication failures when used in partition and/or row keys in tables. However, batch operations can be used if your partition and/or row key needs to use those values, so you would have to use batch operations to work around this issue.

Summary

This blog post has served as an overview of the Windows Azure Storage Client libraries for Windows Runtime and has highlighted some significant points that differ from the desktop implementation. We are committed to providing a great development experience for Windows Runtime developers that fully exploits the Windows Runtime platform. We welcome any feedback that you may have, feel free to leave comments below,

Joe Giardino

Serdar Ozler

Veena Udayabhanu

Justin Yu

Windows Azure Storage

Resources

Get the Windows Azure SDK for .Net