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:
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
- Download the Storage Client libraries for Windows 8
- Download the Windows Azure SDK
- Windows Azure SDK for .Net source code on GitHub
Comments
Anonymous
February 03, 2013
Thanks for releasing this library. This is exactly what I was looking for. However, I could not find any sample to learn how to use it. For example, I don't know how to use UploadFromStreamAsync. Could you please point me to any online sample if exists? Thanks.Anonymous
February 05, 2013
The main difference between the RT and .Net 4.0 library is that the former utilizes the async/await pattern while the latter currently exposes Sync and APM methods. That being said the samples on the getting started page are almost directly usable in an RT app by merely appending the Sync names with the Async postfix and awaiting them. You can view the getting started pages below. Also be aware that due to restrictions in win RT when projecting to JavaScript all generic table objects are located in a extension assembly (.Tables.dll) that is usable via c# & vb. www.windowsazure.com/.../blob-storage www.windowsazure.com/.../table-services www.windowsazure.com/.../queue-service Hope this helps, joeAnonymous
March 14, 2013
Can you please show how to use this storage client with the WinRT BackgroundUploader? Thanks, MichaelAnonymous
March 15, 2013
You can definitely use BackgroundUploader to upload blobs. Please follow the steps below:
- Create a SAS token with Write permissions for the blob to be uploaded.
- Append the SAS token to the blob's URI.
- Create a new BackgroundUploader object and set its Method to "PUT".
- Add "x-ms-blob-type" header to it with the value "BlockBlob".
- Make sure that the content to be uploaded is smaller than 64MB.
- Start the upload operation and wait until the operation completes (you can also monitor its progress).
Anonymous
January 28, 2015
I tested this .winmd library in universal Windows apps, the blobContainer->CreateIfNotExistsAsync() method failed in Windows Phone 8.1 ( both C# and C++/CX ). I wonder if there's such issue in your library.Anonymous
January 29, 2015
This is a known issue. We don’t support universal apps in the version of the client library you are using. We have however added support for Universal applications in our (v4.3.0) that is available on nuget here - www.nuget.org/.../WindowsAzure.Storage. Please give that a try and let us know if you face any issues.Anonymous
February 01, 2015
The comment has been removed