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;

        }

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.

Changing Development Perspectives – Entity Framework and Code First

It is until the last 2 projects I’ve been working that I started to use code first. This is the first article of a series I plan to write on my experiences on this topic.

I have to recognize my friend and supervisor at my new job at Zgura for promoting its use in our development projects. Now I have had the opportunity to work with it, I’ll argue for its use, even if I already have an existent database, no doubts when starting with a new one.

It is great to use it with MVC 4. You just have to create your Models folder (we usually keep that in another project, at the VS solution), add classes, decorate properties as necessary, enable migrations and update database.

The concept works great as, after the initial learning curve, it helps to increase greatly speed of development, more if it is combined with view models.

Tip: if you keep the models in a separated project, remember to let the system know what is the name of the project containing the models to be used by code first migrations:

Enable-Migrations -ProjectName “MyProjectModelName” -StartUpProjectName “MyStartupProjectName”

These instructions for migrations are executed from the menu Tools/Library Package Manager/Package Manager Console in Visual Studio 2012.

Cheers.