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.