Upload and download file to Azure Blob storage

Windows Azure includes a storage service that allows us to store binary and text data as files. This data is stored in BLOB (binary large object). For each Azure subscription we can have up to 5 storages accounts. Each storage account can have up to 100TB of data. More information at: Azure Storage.

We can use BLOBS to store files from an application. Two operation we will need to implement will be upload and download files.

I have implemented both, upload and download methods and use in MVC 4 web applications running on Azure.

I’m showing here code for upload and download methods, the kind I use with MVC 4 web app. In this case, although we are deploying to Azure, we are doing it to a Azure website, so no need for having a cloud project in the application solution. I implemented these methods at a separated model project.

public class AzureStorage
    {
        public void UploadToBlob(string fileName, Stream stream, string containerName)
        {
            //Bellow, not working, use this if using cloud project, when deploying to services
            //CloudStorageAccount storageAcct = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);

            CloudStorageAccount storageAcct = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

            CloudBlobClient blobClient = storageAcct.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
            stream.Position = 0;
            using (var fileStream = stream)
            {
                blockBlob.UploadFromStream(fileStream);
            }
        }
public string DownloadBlob(string fileName, string containerName)
        {
            string uri = string.Empty;

            CloudStorageAccount storageAcct = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

            CloudBlobClient blobClient = storageAcct.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            using (var fileStream = File.OpenWrite(fileName))
            {
                blockBlob.DownloadToStream(fileStream);
            }
            uri = @"http://MyAccountName.blob.core.windows.net/" + containerName + "/" + fileName;
            return uri;
        }

As I was implementing the methods in a separated project (Model, in my case) I had to install Windows Azure Storage library, from Nuget and System Configuration library. In addition, be aware that I’m using release 2 of Azure libraries (instructions to use may change on previous versions of these libraries).

One of the practical uses for upload and download is for generating files using EP Plus and saving them at blob so to allow for later download by users. I’ll write another article to show how to use EPPlus. One of the interesting aspects of its use I’m currently implementing is mixing localization and use of localized data annotations so, instead for example writing the DisplayName of a property at a class like:

[DisplayName(“Inventory Code”)]

I use something like:

[Display(“Inventory_Code”)]

Where Inventory_Code is a resource key that points to a value, so, it could be Inventory Code or Código de Inventario. Now, imagine, you only have to set the data annotation at the property level and that will be used by views helpers to show the display values. In addition, I’m using data annotations for the headers I set for the Excel file I generate using EPPlus so localization will apply too to generated files.

More in following posts.

Cheers.

Note: in the specific case I was working on, since what I want is have the user to download files directly from Azure Blob, I just had to use the following code for downloading:

public string DownloadBlob(string fileName, string containerName)
        {
            return @"http://MyStorageAccountName.blob.core.windows.net/" + containerName + "/" + fileName;

        }

Testing sample REST service using Web API and Azure

I did the example at http://www.windowsazure.com/en-us/develop/net/tutorials/rest-service-using-web-api/

As I was discussing with Anders and Alejandro in a previous post, there is another alternative to access data models and that is using Web API and script blocks. I think this sample helps to clarify in how to do that.

The key parts concerning use of Web API, I believe, for this sample are:

public string Self
        {
            get
            {
                return string.Format(CultureInfo.CurrentCulture,
                    "api/contacts/{0}", this.ContactId);
            }
            set { }
        }

At the Contact class definition.

Notice the use of the property Self at the script block at the Index view for Home controller. Notice how Self property is used to connect with the methods at the API type controller Contacts.

You can see the site at http://contactmgr23.azurewebsites.net/. You can also try adding /api/contacts to the URL and see what happens, it will be shown differently at Firefox and Chrome than as in IE.

Note:Julio Avellaneda has a serie of posts in Spanish on Web API. http://julitogtu.com/category/asp-net-web-api/ Julio participates too at FB group Desarrolladores Nicaragua.

MVC 4 Views and Razor code (and showing an aggregation from an entity)

This is an example situation where Razor can be useful to allow code on a view: in this case, I have a view model like this one (very simplified):

public class Product
{
public Guid ProductId {get;set;}
public string Description {get;set;}

public virtual List ProductTransactions {get;set;}

}

public class ProductTransaction
{
public Guid TransactionId {get;set;}
public decimal Amount {get;set;}

public Guid ProductId {get;set;}
[ForeignKey("ProductId")]
public virtual Product Product {get;set;}

}

then, if I want to see a list of products with total amounts, in my view, I could use something like this:

<table>
  <thead>
    <tr>
      <td>
          @Html.LabelFor(x => x.Product[0].Description)
      </td>
      <td>
           @Html.LabelFor(x => x.Product[0].ProductTransactions[0].Amount)
      </td>
     </tr>
   </thead>
   <tbody>
    @foreach (var product in Model.Product) 
      {
       <tr>
         <td>
             @Html.DisplayFor(x => product.Description)
         </td>
        <td>
           @{ decimal totalAmount=0;
           foreach (var transaction in Product.ProductTransactions)
              {
                totalAmount= totalAmount+ transaction.Amount;
               }
            @Html.DisplayFor(x => totalAmount)
            }
       </td>
      </tr>
      }
    </tbody>
</table>

Of course this is not the complete code of the View, I just focused on what’s relevant to the use of code inside the view using Razor, for a specific purpose, in this case, obtain aggregation of the Amount for each one of the products in the corresponding entity (at the DB).

Cheers.