Working with Windows Azure BLOB storage



There are plenty of articles and blog posts about theoretical concept of BLOB already available. So I am not going to rediscover that wheel. What you can expect from this post is a code walkthrough to perform

  1. Insert Image in BLOB
  2. Delete Image from BLOB
  3. Fetch Image from BLOB
  4. Create a container in BLOB
  5. Ensure Container is available

Before I go to the walkthrough, one simple explanation of a BLOB is, "BLOB is a type of storage in Windows Azure allows you to work with big size files".

I may discuss the full theoretical concept of a BLOB in some other post but for the purpose of this post, I have already described BLOBs.
So let us start coding.
  1. Open Visual Studio as administrator
  2. Create a New project
  3. Select CLOUD project from Cloud tab
  4. Add a web Role

Follow the below steps:

Add Connection string for BLOB storage

To add a connection string you need to add it as a setting of the Web Role. To add a setting, right click on the Role and select Properties.

AzureBlob1.gif

Select the Settings tab and add a new setting. To add a new setting you will have to click Add Setting at top. Give a name to setting. Here I am giving name DataConnectionString. From the drop down select Connection String as a type.

AzureBlob2.gif

Once you have provided a name and type for the new setting, click on the extreme right to provide a value to the setting. I am going to use local storage. If you are planning to use Azure Storage then you will have to provide"
  1. Azure storage account credential
  2. BLOB endpoint.
  3. For local development fabric selects first option.

    AzureBlob3.gif

Add Container Name

To add Container name, essentially you need to add one more setting.

AzureBlob4.gif

I am giving the name as ContainerName; the data type is String and set the value to mygallery
There are a few rules you need to keep in mind when providing a name for the container:
  1. Must start with a number or letter or dash.
  2. Must contain only lower case
  3. Must be minimum 3 in length and maximum 63 characters in length.

Create a BLOB Utility class

I am going to create a Utility class. This class will contain all the basic functions related to BLOB storage.
I am going to have four basic functions:
  1. Get the Container
  2. Ensure Container exist
  3. Upload a file
  4. Delete a file
  5. Retrieve a file

Right-click on the WebRole project and add a class. For the name of the class I am using BLOBUtility.

AzureBlob5.gif

Make sure you have added the below namespaces and made the class static.

Microsoft.WindowsAzure;
Microsoft.WindowsAzure.ServiceRuntime;
Microsoft.WindowsAzure.StorageClient;


The basic structure of your class should look like below image:

AzureBlob6.gif

Write a function to get the Container

In the BLOBUtility static class, write a static function called GetContainer(). This function will return CloudBLOBContainer.

AzureBlob7.gif

In thge above function,

first I am getting the storage account. Make sure that you are passing the correct Connection String Name. If you would have noticed, I created a connection string of name "DataConnectionString" in previous steps. So as input, I am passing DataConnectionString.

The second task I am doing is creating a BLOB Client.

The third task I am doing is getting a reference to the container by passing the container name. Again if you would have noticed in previous steps I created a container of name "ContainerName".

Write a function to ensure that the container exists

In the BLOBUtility static class, write a static function called EnsureContainer(). This function will not return anything.

AzureBlob8.gif

In the above function,

first I am getting the Container and if the container does not exist, create it. I am setting the Public Access permission to Container.

Write a function to save an Image

In static class BLOBUtility write a static function called InsertImage(). This function will not return anything.

AzureBlob9.gif

In the above function, you need to pass metadata associated with the file as input parameter. A very important point worth noting here is to ensure you are passing an ID as input parameter. At the time of calling, pass a unique GUID as ID. Essentially there are three parts in the above function:
  1. Creating Metadata from input parameters.
  2. Adding Metadata to the BLOB
  3. Uploading Byte Array to the BLOB.

Write a function to Delete Image

In static class BLOBUtility write a static function called DeleteImage(). This function will not return anything.

AzureBlob10.gif

In the above function, as the input parameter, pass the URI of the image to delete. Using image URI, get the BLOB reference and delete image file.

Upon finishing the DeleteImage function, your BLOB Utility class is ready to use.

BLOBUtility.cs

using System;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Collections.Specialized; 

namespace WebRole1
{
    public static  class BLOBUtility
    {
        public static CloudBlobContainer GetContainer()
        {
            try
            {
                //var account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
                var account = CloudStorageAccount.Parse
                               (RoleEnvironment.GetConfigurationSettingValue
                               ("DataConnectionString"));

                 var client = account.CreateCloudBlobClient();
                var blobReference = client.GetContainerReference(RoleEnvironment.GetConfigurationSettingValue
("ContainerName"));
                return blobReference;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static void EnsureContainer()
        {
            var container = GetContainer();
            container.CreateIfNotExist();
            var permission = container.GetPermissions();
            permission.PublicAccess = BlobContainerPublicAccessType.Container;
            container.SetPermissions(permission); 
        }

        public static void InsertImage(string Id, string name, string fileName, string contentType, byte[] imageData)
        {
            var blob = GetContainer().GetBlobReference(name);
            blob.Properties.ContentType = contentType;
            var metaData = new NameValueCollection();
            metaData["Id"] = Id; 
            metaData["FileName"] = fileName;
            metaData["ImageName"] = name;
            blob.Metadata.Add(metaData);
            blob.UploadByteArray(imageData);
         }

        public static void DeleteImage(string imageURI)
        {
            var blob = GetContainer().GetBlobReference(imageURI);
            blob.DeleteIfExists();
        }
    }
}


Design aspx page

Default.aspx

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="WebRole1._Default" %>
 
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Welcome to ASP.NET!
    </h2>
    <p>
        <asp:Label ID="Label1" runat="server" Text="Select Image to Upload"></asp:Label> <br />
         <asp:Label ID="Label2" runat="server" Text="Give File Name "></asp:Label>
        <asp:TextBox ID="txtFileName" runat="server" Width="114px"></asp:TextBox> <br />
        <asp:FileUpload ID="FileUpload1" runat="server" />
    </p>
    <asp:Button ID="btnUpload" runat="server" Text="Upload Image" Width="209px" 
        onclick="btnUpload_Click" />
   <div>
    <asp:ListView ID="images" runat="server" onitemdatabound="OnBlobDataBound">
            <LayoutTemplate>
                <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
            </LayoutTemplate>
            <EmptyDataTemplate>
                <h2>No Data Available</h2>
            </EmptyDataTemplate>
            <ItemTemplate>            
                <div class="item">
                    <ul style="width:40em;float:left;clear:left" >
                        <asp:Repeater ID="blobMetadata" runat="server">
                        <ItemTemplate>
                            <li><%# Eval("Name"%><span><%# Eval("Value"%></span></li>
                        </ItemTemplate>
                        </asp:Repeater>
                     <li>
                            <asp:LinkButton ID="deleteBlob" 
                                    OnClientClick="return confirm('Delete image?');"
                                    CommandName="Delete" 
                                    CommandArgument='<%# Eval("Uri")%>'
                                    runat="server" Text="Delete" oncommand="OnDeleteImage" />
 
                    </ul>
                    <img src="<%# Eval("Uri") %>" alt="<%# Eval("Uri") %>" style="float:left"/>
                </div>
            </ItemTemplate>
        </asp:ListView>
   </div>    
</asp:Content
>


I have put on the aspx page:
  1. One textbox
  2. One File Upload Control
  3. One List view with repeater control

I am binding the List box with all the Images from the BLOB.

AzureBlob11.gif

In the above function I am setting the Data Source of the repeater control Meta data values from the BLOB.

To bind the image control with Image from BLOB:

AzureBlob12.gif

For your reference the full source code is as below:

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient; 
 
namespace WebRole1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                BLOBUtility.EnsureContainer();
 
            }
 
           this.LoadImage();
        }
 
        private void LoadImage()
        {
 
            images.DataSource = BLOBUtility.GetContainer().ListBlobs(new BlobRequestOptions()
              {
                  UseFlatBlobListing = true,
                  BlobListingDetails = BlobListingDetails.All
              });
            images.DataBind();
 
        }
 
        protected void btnUpload_Click(object sender, EventArgs e)
        {
            BLOBUtility.InsertImage(Guid.NewGuid().ToString(),txtFileName.Text,FileUpload1.FileName ,
FileUpload1.PostedFile.ContentType, FileUpload1.FileBytes);
            LoadImage();
        }
 
        protected void OnDeleteImage(object sender, CommandEventArgs e)
        {
           
                if (e.CommandName == "Delete")
                {
                   
                    BLOBUtility.DeleteImage((string)e.CommandArgument);
                }
                LoadImage();
 
         }          
 
        protected void OnBlobDataBound(object sender, ListViewItemEventArgs e)
        {
            if (e.Item.ItemType == ListViewItemType.DataItem)
            {
                var metadataRepeater = e.Item.FindControl("blobMetadata"as Repeater;
                var blob = ((ListViewDataItem)(e.Item)).DataItem as CloudBlob;

               
                if (blob != null)
                {
                    if (blob.SnapshotTime.HasValue)
                    {
                        var delBtn = e.Item.FindControl("deleteBlob"as LinkButton;
                        if (delBtn != null) delBtn.Text = "Delete Snapshot";
                      
                    }
 
                    if (metadataRepeater != null)
                    {
                        //bind to metadata
                        metadataRepeater.DataSource = from key in blob.Metadata.AllKeys
                                                      select new
                                                      {
                                                          Name = key,
                                                          Value = blob.Metadata[key]
                                                      };
                        metadataRepeater.DataBind();
                    }
                }
            }
        }
    }
}

erver'>
Up Next
    Ebook Download
    View all
    Learn
    View all