ASP.NET WebAPI 2 - Stream Windows Azure blobs
With this article, I will show all steps you need to complete to create an ASP.NET WebAPI 2 to upload and download your documents to a Windows Azure Storage.
STEP 1 - Install Windows Azure SDK for .NET
This could be done through Microsoft Web Platform Installer
Select the option Add on item Windows Azure SDK for .NET (VS 2013) -2.2, and the component will be installed on your machine.
http://code.msdn.microsoft.com/site/view/file/111368/1/5187.Publish1.png
STEP 2 - Create Azure Account
You need to get a Windows Azure account. Everyone can open a Windows Azure account for free.
Check the link below for more information.
http://www.windowsazure.com/en-us/pricing/free-trial/
STEP 3 - Create Blob Storage on Windows Azure
After get access to an Azure Account, we need to create a blob storage.
So for that we need to select the option New on the left bottom of our web page and then select the option Data Services -> Storage -> Quick Create and give a name to your storage.
On this case our blob storage will have the name "blobstorages".
http://code.msdn.microsoft.com/site/view/file/111370/1/2.png
After create the blob storage, we need to get the keys that will be used on Web API to access to storage. For that, select the created storage and on the bottom of the page check the option Manage Access Keys. This option, give us the name of our storage and the key.
http://code.msdn.microsoft.com/site/view/file/111372/1/3.png
Now that we have our storage and the credentials to connect, the next step will be the creation of a container, where we will put our documents. Select the option Create Container and give a name to it (on this example, the container will be named "documents").
http://code.msdn.microsoft.com/site/view/file/111373/1/4.png
STEP 4 - Create ASP.NET Web API Application
I will be using Visual Studio 2013 as my development environment. Our first step will be to create an ASP.NET Web Application project based on the Web API template.
- Open Visual Studio 2013 and create a new project of type ASP.NET Web Application.
- On this project I create a solution called WebAPI.
http://code.msdn.microsoft.com/site/view/file/111377/1/5.png
- Press OK, and a new screen will appear, with several options of template to use on our project.
- Select the option WebAPI.
- The solution will be created.
http://code.msdn.microsoft.com/site/view/file/111383/1/6.png
- Set the connection string to connect to the Azure blobs. You can just add the following setting to your Web.config.
XML
<connectionStrings>
<add name="Azure" connectionString="DefaultEndpointsProtocol=https;AccountName=blobstorages;AccountKey=+wMZaUv/..." />
</connectionStrings>
Now in order to interact with the Azure Blobs, you need to add the reference to the following assemblies:
- Microsoft.WindowsAzure.Storage
For that we will install a Nuget Package named Windows Azure Storage, as I show on the next image.
So on the Visual Studio 2013, select the follow menu option:
Tools-> Library Package manager -> Manage NuGet Packages for Solution
Search for Windows Azure Storage and select the option Install.
http://code.msdn.microsoft.com/site/view/file/111379/1/7.png
This option will install automatically the Nuget Package.
The next step will be the creation of our controller.
ApiController implements an HTTP POST action handling the file upload. Note that the action returns Task<T> as we read the file asynchronously.
The first thing we do is check that the content is indeed "multipart/form-data". The second thing we do is creating a MultipartFormDataStreamProvider which gives you control over where the content ends up. In this case we save the file in the folder "App_Data". It also contains information about the files stored.
If you want complete control over how the file is written and what file name is used then you can derive from MultipartFormDataStreamProvider, override the functionality you want and use that StreamProvider instead.
Once the read operation has completed we check the at is done we read the content asynchronously and when that task has completed we generate a response.
http://code.msdn.microsoft.com/site/view/file/111380/1/8.png
Now, let’s create the Web API actions. Below, I’ve created a simple DocumentController that will support the following actions:
- POST: Will upload files, this will only support multipart/form-data format
- GET: Will list the files that have been uploaded
C#
public async Task<HttpResponseMessage> Post()
{
var context = new StorageContext();
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
// Get and create the container
var blobContainer = context.BlobClient.GetContainerReference(CONTAINER);
blobContainer.CreateIfNotExists();
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names for uploaded files.
foreach (var fileData in provider.FileData)
{
var filename = fileData.LocalFileName;
var blob = blobContainer.GetBlockBlobReference(filename);
using (var filestream = File.OpenRead(fileData.LocalFileName))
{
blob.UploadFromStream(filestream);
}
File.Delete(fileData.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
C#
public async Task<HttpResponseMessage> Get(string id)
{
var context = new StorageContext();
// Get and create the container
var blobContainer = context.BlobClient.GetContainerReference(CONTAINER);
blobContainer.CreateIfNotExists();
var blob = blobContainer.GetBlockBlobReference(id);
var blobExists = await blob.ExistsAsync();
if (!blobExists)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "File not found");
}
HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.OK);
Stream blobStream = await blob.OpenReadAsync();
message.Content = new StreamContent(blobStream);
message.Content.Headers.ContentLength = blob.Properties.Length;
message.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(blob.Properties.ContentType);
message.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = blob.Name,
Size = blob.Properties.Length
};
return message;
}
Running the Web application, this will be our result. On the API menu, exists an help page, with all the actions implemented.
http://code.msdn.microsoft.com/site/view/file/111381/1/9.png
STEP 5 - Test with a .NET Client
HttpClient is an extensible API for accessing any services or web sites exposed over HTTP.
The HttpClient API was introduced as part of the WCF Web API but is now available as part of ASP.NET Web API in.NET Framework 4.5. You can use HttpClient to access Web API methods from a code-behind file and from services such as WCF.
The code snippet shown creates an HttpClient object and uses it for asynchronous access to sample API methods. Refer the code comments to understand the code snippet.
First we need to add a Nuget package named System.Net.HTTP that contains the required classes
With that in place we can start using the HttpClient instead.
Windows Azure Resources
Some good resources about Windows Azure could be found here:
- Windows Azure Portal
- My personal blog: http://joaoeduardosousa.wordpress.com/
Code Sample
All of this sample can be found and downloaded from the Microsoft Code Gallery: