ServiceStack Tutorial: How to upload and download binary files from Azure

ServiceStack is an excellent framework for creating WebServices with dotNet. When I first started to build SOA in C#, I inevitably ran into the slowness and heaviness of WCF and the immaturity of Web APIs.
Looking for alternatives, I came across ServiceStack’s site. I discovered this elegant, well-designed, fast and intuitive framework.

If you’re not familiar with ServiceStack, I suggest you to read this brief introduction on the official website.

This tutorial will deal with the issue of uploading/downloading binary files to/from Azure via ServiceStack. I’ll assume a basic knowledge of ServiceStack and Azure.


NuGet packages required:

DTO

First thing first, we code DTOs. For the upload, just enter the extra parameters we want to send with the file (eg. A string “Author”).

[Route("upload")]
public class UploadRequest: IReturn<UploadResponse>
{
    public string Author { get; set; }
}
public class UploadResponse
{
    public bool Result { get; set; }
}

The download request returns a stream with the requested data as an attachment to the user’s  browser. Note: it’s important to dispose the stream once the transfer is complete, to avoid returning a damaged file.

[Route("/download")]
public class DownloadRequest : IReturn<FileStreamResult>
{
     public string FileName { get; set; }
}

public class FileStreamResult : IHasOptions, IStreamWriter
{
     private readonly Stream _responseStream;
     public IDictionary<string, string> Options { get; private set; }

     public FileStreamResult(Stream responseStream, string fileName)
     {
         _responseStream = responseStream;
         Options = new Dictionary<string, string>; {
              {"Content-Type", "application/octet-stream"},
              {"Content-Disposition", "attachment; filename=\"" + fileName + "\";"}
         };
     }

     public void WriteTo(Stream responseStream)
     {
         if (_responseStream == null)
             return;

         _responseStream.WriteTo(responseStream);
         responseStream.Flush();
         //dispose
         responseStream.Dispose();
     }
}

Service
And here is the service that handles upload and download of binary files:

public class AzureStorageService : Service
{
        private string azureUsr = "YOUR AZURE STORAGE ACCOUNT USERNAME";
        private string azurePwd = "YOUR AZURE STORAGE ACCOUNT KEY";
        private string azureContainer = "YOUR CONTAINER NAME";
        private StorageCredentials azureCredentials;
        private CloudStorageAccount azureStorageAccount;
        private CloudBlobClient azureBlobClient;
        private CloudBlobContainer azureBlobContainer;

        public AzureStorageService()
        {
            //Initializes azure objects
            azureCredentials = new StorageCredentials(azureUsr, azurePwd);
            azureStorageAccount = new CloudStorageAccount(azureCredentials, true);
            azureBlobClient = azureStorageAccount.CreateCloudBlobClient();
            azureBlobContainer = azureBlobClient.GetContainerReference(azureContainer);
        }

        public object Post(UploadRequest request)
        {
            //Get the file stream from request
            var inputStream = Request.Files[0].InputStream;
            
            //Creates a new empty blob reference
            var blob = azureBlobContainer.GetBlockBlobReference(Request.Files[0].FileName);
            
            //Upload binary data
            blob.UploadFromStream(inputStream);

            return new UploadResponse() { Result = true };
        }

        public object Get(DownloadRequest request)
        {
            //Get reference to blob that contains the requested object
            var blob = azureBlobContainer.GetBlockBlobReference(request.FileName);
            MemoryStream return_stream = new MemoryStream();
            blob.DownloadToStream(return_stream);
            return_stream.Position = 0L;
            return new FileStreamResult(return_stream, request.FileName);
        }
}

You can download the complete example from here.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s