The blog of dlaa.me

Gettin' blobby with it [Sharing the code for a simple Silverlight 4 REST-based cloud-oriented file management app for Azure and S3]

I've described the "app building" process before in this post about my HeadTraxExtreme sample for the Silverlight 3 Beta and a later in this update of HeadTraxExtreme for the Silverlight 3 RTW. The gist is that:

... everyone comes up with an idea for a medium-sized application they think could be built with the bits at hand - then goes off and tries to build as much of that application as they can before time runs out. The emphasis is on testing new scenarios, coming up with creative ways of integrating components, and basically just getting the same kind of experience with the framework that customers have every day. Coming up with a beautifully architected solution is nice if it happens, but not specifically a goal. Rather, the point is to help people take a holistic look at how everything works together...

App building is a great way to get exposure to parts of the product you don't normally deal with and can help give team members a more complete view of the platform they work on. I had another app building opportunity recently and my goal was to create a utility application I've been wanting for a while.

Here's where I got in the bit of time I had:

 

BlobStore with silly sample data

Disclaimer: In case it's not completely obvious, none of the file names above is accurate. :)

 

The Sales Pitch

Did you ever want an easy way to transfer files between two machines on semi-isolated networks (ex: home and work)? Looking for an easier way to publish content to the web? Tired of sending yourself files as email attachments all the time? Sneaker-net got you down? Well, your dreams have just come true!

BlobStore is the hot new craze that's taking the world by storm. It's a small, lightweight Silverlight 4 application that acts as a basic front-end for the Windows Azure Simple Data Storage and the Amazon Simple Storage Service (S3)! Just run the BlobStore app, point it at a properly provisioned Azure or S3 account (see below for details on provisioning), and all of a sudden sharing files with yourself and others becomes as simple as dragging and dropping them! BlobStore makes it easy to manage your files by providing a feature-rich (okay, that's an exaggeration) interface that allows you to view, download, or delete files and copy their URL to the clipboard easy-peasy. Logon credentials are stored on your machine so there's no need to remember long account passwords - once you've connected once, future connections are simple and painless.

But wait, there's more!

If you download right now, you'll also get the complete source code from which you can explore all the inner workings of this life-changing application. Included with every code download is a free REST wrapper for basic Azure and S3 blob access that handles all the tricky Authorization header details for you. It's almost guaranteed to make your next Azure/S3 application a snap to develop and a wild success in the marketplace.

So now how much would you pay? :)

 

BlobStore login screen

 

Featured Silverlight 4 Features

  • Asynchronous networking
    • Windows Azure REST API
    • Amazon S3 REST API
    • Authorization HTTP header
    • Custom HTTP verbs
    • Client HTTP stack
    • Real-time progress indication
  • View/view model separation
    • INotifyPropertyChanged interface
    • ICommand interface
    • Simple DelegateCommand implementation
    • Extensive data binding
  • Design-time experience
    • Design-time data
    • Design tool-friendly experience
  • Isolated Storage
    • For user preferences
    • For files
  • Controls
    • Custom DependencyPropertys
    • Visual State Manager
    • Custom control Templates
    • Custom UserControls
  • Clipboard access
  • Right click support
  • Custom unhandled exception handler

Potential Enhancements (TODOs)

  • Smooth various rough edges
  • Support running out-of-browser
  • Ability to automatically provision new Azure/S3 accounts
  • Better handling of web service failures
  • Encrypt logon information in isolated storage
  • Additional metadata for each blob (file size, MD5 hash, etc.)
  • Support Silverlight-based file downloads (i.e., SaveFileDialog)
  • Support marking blobs private (i.e., not world-readable)

Potential v.Next Enhancements (features not supported by Silverlight 4)

  • Set/get clipboard access for data (ex: images, files)
  • Support for downloading by dragging files out of the plug-in

Notes

  • In addition to supporting Azure and S3, BlobStore allows you to use Silverlight's isolated storage for the blob service. This works fine for playing around and general experimentation, but it's important to note that the web browser isn't able to download from isolated storage, so files "uploaded" to isolated storage can't be "downloaded" with the browser.
  • Access to an isolated storage "account" requires a non-empty account name and key - any name and key will work.
  • Isolated storage support is present only for testing purposes (and so people without a provisioned account can play around); I haven't verified that BlobStore works well if access to isolated storage has been disabled or runs out of space.
  • Developer documentation for the two online services can be found at the following locations: Windows Azure, Amazon S3
  • Despite my Silverlight Toolkit pedigree, BlobStore uses no Toolkit or SDK controls - it's 100% core framework-y goodness!

 

[Click here to run the BlobStore application in your browser.]

[Click here to download the complete source code for the Silverlight 4 BlobStore sample.]

 

BlobStore upload progress screen

 

Provisioning

Before BlobStore can access an Azure/S3 account, that account needs to be provisioned to allow access by a Silverlight browser-based application and permit unauthenticated third parties to download content. Steve Marx has a great overview of provisioning an Azure account - the basic steps are to create the special $root container, make it world-readable, and upload a clientaccesspolicy.xml file that lets Silverlight know the cross-domain access is okay. For an S3 account, the concept is the same, but the implementation is a bit simpler - just upload a clientaccesspolicy.xml file and make it world-readable.

These one-time provisioning steps can be done manually, in code, or with one of the public tools for Azure or S3. The clientaccesspolicy.xml file I use is taken from Steve's example with a tweak to make support for http and https more explicit:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-methods="*" http-request-headers="*">
        <domain uri="http://*" />
        <domain uri="https://*" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true" />
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

 

Summary

BlobStore was a fun project to work on and it gave me some nice exposure to Silverlight's networking stack (which I don't normally get a chance to use). There are some rough edges I didn't get around to smoothing over, but on the whole I think BlobStore turned out pretty well: it's small and quick to download, easy to use, it simplifies something I do every day, and it was a great learning experience!

Aside: You can even use BlobStore to publish Silverlight applications (just upload the XAP and HTML file), so it's got that recursive thing going for it, too...

I'd never claim BlobStore is the best example of application design, but I did try to follow "best practices" in most cases; there are some interesting techniques in there that some of you may not have seen in action. And if writing and sharing BlobStore helps others learn how to develop better Silverlight applications, we all win. :)

 

Enjoy!