Tuesday, October 7, 2008

Silverlight / WCF Flickr Style Multi-file uploader control and service

Ever since the early early betas of Silverlight, users have been looking to create the first obvious application of this new technology: the ability to upload multiple files at once with a progress meter for each. This was accomplished very well during the Silverlight 1.1 beta period here; however, there were a number of breaking changes as well as improvements with the beta of Silverlight 2.0.

As the requirement started to bubble up for some of my clients, I decided to dive in and create such a control. I am posting it here for all to make up for all of the times I've incorporated others' free code into my work in the past. Here goes:

Server Architecture
The server side consists of two separate WCF services: FileInfoService and FileUploadService. The FileInfoService is an easy-to-use basicHttpBinding service which is the standard WCF programming model for the Silverlight / WCF stack. This service exposes two basic methods: ListFiles and DeleteFile whose function is, well, obvious.

The second service, FileUploadService, supports a streamed file upload to the server. I decided to use a REST service because other WCF streaming service bindings actually generated a byte array instead of a service on the Silverlight client side...not helpful if you're trying to create a progress bar to track upload. For a full explaination of the implementation of this service, please see Carlos Figueira's excellent posting on the subject.

Client Architecture
The client is nothing special except for the upload process. The upload is handled using a WebHttpRequest which streams the file to the server. The BackgroundWorker class is used to perform the upload in a background thread periodically calling back up to the client to update the progress of the upload.

Demo and Source

The control is demonstrated here.
This demo shows the uploader in action. Since it is a demo, it is limited to 2MB files. Furthermore, files are streamed to the server, yet are not saved, so don't be surprised if you can't see them. Disabling this in the downloaded code is a matter of setting the Demo appsetting in Web.config as well as the Demo variable in FileUploader.ConfigConstants.

The source for the project can be downloaded here.

Conclusion
The allure of creating full-fledged C# applications on the browser is very appealing. With the advent of Silverlight 2.0, this will become a reality. This control is one of the first things that comes to mind when we think about using such tools to fill in the gap between web-based application and desktop apps. While it was more difficult than I had originally envisioned, it proved to be a whirlwind tour which included both Silverlight and WCF.

This implementation comes with some caveats. The code was written as a good starting point for adding this functionality to any silverlight application. It will require the addition of better security as well as more validation. Finally the FileHandler factory in the client may seem like overkill. This was added to abstract the end-points from the code in order to simplify the inevitable transition to other storage services such as Amazon's S3 or Microsoft's up-and-coming Cloud Services.

So, next steps might include:
  • Improved validation.
  • Control of the number of concurrent streams / uploads.
  • Better control for file size.
  • Configuration for supported file types.
  • S3 Connector for Amazon S3 services (Not as big a reach as one might think).
  • Skins to enable a complete file / folder structure.

Apologies for an abridged post...I just don't have more time to keep going on this little project. Download that source, good luck and have fun!

0 comments: