Sunday, December 23, 2012

How to use Azure storage for uploading and displaying pictures.

Basic set up of Azure storage for local development and production.

This is a somewhat completion of the following guide from http://www.windowsazure.com/en-us/develop/net/how-to-guides/blob-storage/ that also involves a practical example that I believe is commonly used, i.e. upload and present an image from a user.

 

First we set up for local storage and then we configure for them to work on a web role.

Steps:

1. Configure connection string locally.

2. Configure model, controllers and razor views.

 

1. Setup connectionsstring

1_SetupSettingsForConString

1.1 Right click your web role and choose “Properties”.

1.2 Click Settings.

1.3 Add setting.

1.4 Name your setting. This will be the name of the connectionstring.

1.5 Click the ellipsis to the right. (the ellipsis appear when you mark the area.

1.6 The following window appears- Select “Windows Azure storage emulator” and click ok.

1_5_ChooseWindowsAzureEmulator

 

Now we have a connection string to use. To be able to use it we need to make sure we have windows azure tools for storage.

2.1 Click Tools –> Library Package manager –> Manage Nuget packages for solution.

2.2 This is what it looks like after it has been added.

2_2_DownlaodAzureStorageTools

 

Now on to what the code should look like.

3.1 First we need a view which collects images to upload. Here Index.cshtml.

   1: @model List<string>   
   2:  
   3: @{
   4:     ViewBag.Title = "Index";
   5: }
   6:  
   7: <h2>Index</h2>
   8: <form action="@Url.Action("Upload")" method="post" enctype="multipart/form-data">
   9:  
  10:     <label for="file">Filename:</label>
  11:     <input type="file" name="file" id="file1" />
  12:     <br />
  13:     <label for="file">Filename:</label>
  14:     <input type="file" name="file" id="file2" />
  15:     <br />
  16:     <label for="file">Filename:</label>
  17:     <input type="file" name="file" id="file3" />
  18:     <br />
  19:     <label for="file">Filename:</label>
  20:     <input type="file" name="file" id="file4" />
  21:     <br />
  22:     <input type="submit" value="Submit" />
  23:    
  24: </form>
  25:  
  26: @foreach (var item in Model) {
  27:  
  28:     <img src="@item" alt="Alternate text"/>
  29: }

3.2 We need a controller to receive the post. Notice the “containername” string I send to the blobhandler. I use this as a folder for the pictures for each user. If this is not a requirement you could just call it container or anything with small characters directly when creating the container.



   1: public ActionResult Upload(IEnumerable<HttpPostedFileBase> file)
   2:         {
   3:             BlobHandler bh = new BlobHandler("containername");
   4:             bh.Upload(file);
   5:             var blobUris=bh.GetBlobs();
   6:             
   7:             return RedirectToAction("Index",blobUris);
   8:         }

3.3 The handler model. I’ll let the comments speak for themselves.



   1: public class BlobHandler
   2:     {
   3:         // Retrieve storage account from connection string.
   4:         CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
   5:         CloudConfigurationManager.GetSetting("StorageConnectionString"));
   6:  
   7:         private string imageDirecoryUrl; 
   8:  
   9:         /// <summary>
  10:         /// Receives the users Id for where the pictures are and creates 
  11:         /// a blob storage with that name if it does not exist.
  12:         /// </summary>
  13:         /// <param name="imageDirecoryUrl"></param>
  14:         public BlobHandler(string imageDirecoryUrl)
  15:         {
  16:             this.imageDirecoryUrl = imageDirecoryUrl;
  17:             // Create the blob client.
  18:             CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
  19:  
  20:             // Retrieve a reference to a container. 
  21:             CloudBlobContainer container = blobClient.GetContainerReference(imageDirecoryUrl);
  22:  
  23:             // Create the container if it doesn't already exist.
  24:             container.CreateIfNotExists();
  25:  
  26:             //Make available to everyone
  27:             container.SetPermissions(
  28:                 new BlobContainerPermissions
  29:                 {
  30:                     PublicAccess = BlobContainerPublicAccessType.Blob
  31:                 });
  32:         }
  33:  
  34:         public void Upload(IEnumerable<HttpPostedFileBase> file)
  35:         {
  36:             // Create the blob client.
  37:             CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
  38:  
  39:             // Retrieve a reference to a container. 
  40:             CloudBlobContainer container = blobClient.GetContainerReference(imageDirecoryUrl);
  41:  
  42:             if (file != null)
  43:             {
  44:                 foreach (var f in file)
  45:                 {
  46:                     if (f != null)
  47:                     {
  48:                         CloudBlockBlob blockBlob = container.GetBlockBlobReference(f.FileName);
  49:                         blockBlob.UploadFromStream(f.InputStream);
  50:                     }
  51:                 }
  52:             }
  53:         }
  54:  
  55:         public List<string> GetBlobs()
  56:         {
  57:             // Create the blob client. 
  58:             CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
  59:  
  60:             // Retrieve reference to a previously created container.
  61:             CloudBlobContainer container = blobClient.GetContainerReference(imageDirecoryUrl);
  62:  
  63:             List<string> blobs = new List<string>();
  64:  
  65:             // Loop over blobs within the container and output the URI to each of them
  66:             foreach (var blobItem in container.ListBlobs())
  67:                 blobs.Add(blobItem.Uri.ToString());
  68:  
  69:             return blobs;
  70:         }
  71:     }

3.4 So, when the files have been uploaded we will get them to present them to out user in the index page. Pretty straight forward. In this example we only present the image by sending the Uri’s to the view. A better way would be to save them up in a view model containing URI, metadata, alternate text, and other relevant information but for this example this is all we need.


 


4. Now press F5 in your solution to try it out. You can see the storage emulator UI here:


 


4_CheckStorageEmulatorUI


 


4.1 If you get any exceptions or errors I suggest to first check if the service Is running correctly. I had problem with this and they seemed related to the installation and a reboot fixed my problems.


 


4_1_UI


 


5. Set up for Cloud storage. To do this we need to add configuration for cloud just as we did for local in step one.


5.1 We need our keys to do this. Go to the windows Azure menagement portal, select storage icon to the right and click “Manage keys”. (Image from a different blog post though).


 


5_ManageKeys


5.2 Do as in step 1.but replace step 1.6 with:


1.6 Choose “Manually entered credentials”. Enter your account name.


1.7 Paste your Account Key from step 5.1. and click ok.


5_2_SetUpCloudPropertiesConString


 


5.3. Save, publish and run!


Please feel free to ask any questions using the comments form at the bottom of this page. I will get back to you to help you solve any questions. Our consultancy agency also provides services in the Nordic regions if you would like any further support.

No comments:

Post a Comment