Friday, August 2, 2019

Azure Storage CRUD Operations In MVC Using C# - Azure Blob Storage - Part Two

Overview
Azure Blob Storage is used to store the unstructured physical object in Microsoft Cloud. We can access the data over HTTP & HTTPS protocol from anywhere internet connection is available. If we want, we can restrict the access of Blob as public or private. It has the full flavor of cloud elasticity.
You can get more overview of Azure Blob Storage from here.
Concept
Blob storage exposes three resources: your storage account, the containers in the account, and the blobs in a container. You can also add folder into the container. The relation looks like this.

Azure

The blob URL looks like this.
Azure
 You can customize your endpoint with your domain.
NoteThere are some rules to create a container
  1. Container Name should be in lower case
  2. Container Name length must be within 3 characters to 63 characters
  3. Container Name does not support any special character except "-" (dash) 
To create this project, I’m using.
  • .Net Framework 4.6
  • Windows Azure Storage 8.1.1 package
  • Visual Studio 2015
  • MVC 5.0
The scope of work(SOW)
  1. Upload Screen - Here I used an HTML form and input type file.

    Azure
  2. View and Delete Screen - Here, I use an HTML table to view all files in a container. There is a button to Delete the file from Blob Storage.

    Azure
Step 1
Create Azure Storage Account.
Go to https://portal.azure.com and create Azure Storage Account.
Azure
Access Key & Connection String
After creating Azure Storage Account, go to that account and copy the access key and connection string of that account. It will be used in our MVC application.
Azure
Step 2
Create a new empty MVC application. The step to create a new project is File -> New -> Project…
Go to NuGet package manager console window and install -> “Install-Package WindowsAzure.Storage -Version 8.1.1”.
Step 3
Add “BlobManager” class for access Azure Blob. And use two namespaces.
  1. WindowsAzure.Storage;
  2. WindowsAzure.Storage.Blob;
Remove default Constructor from “BlobManager” class. And add a parameterized Constructor with a string parameter. Also, add a private property of “CloudBlobContainer”.
This constructor will create the container if it's not there in Storage and set the permission of the container. We put the Azure Storage Connection String in this constructor, which was declared above.
  1. public class BlobManager  
  2. {  
  3.     private CloudBlobContainer blobContainer;  
  4.   
  5.     public BlobManager(string ContainerName)  
  6.     {  
  7.         // Check if Container Name is null or empty  
  8.         if (string.IsNullOrEmpty(ContainerName))  
  9.         {  
  10.             throw new ArgumentNullException("ContainerName""Container Name can't be empty");  
  11.         }  
  12.         try  
  13.         {  
  14.             // Get azure table storage connection string.  
  15.             string ConnectionString = "Your Azure Storage Connection String goes here";  
  16.             CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);  
  17.   
  18.             CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();  
  19.             blobContainer = cloudBlobClient.GetContainerReference(ContainerName);  
  20.   
  21.             // Create the container and set the permission  
  22.             if (blobContainer.CreateIfNotExists())  
  23.             {  
  24.                 blobContainer.SetPermissions(  
  25.                     new BlobContainerPermissions  
  26.                     {  
  27.                         PublicAccess = BlobContainerPublicAccessType.Blob  
  28.                     }  
  29.                 );  
  30.             }  
  31.         }  
  32.         catch (Exception ExceptionObj)  
  33.         {  
  34.             throw ExceptionObj;  
  35.         }  
  36.     }  
  37. }  
Step 4
Add a public method for Upload file into "BlobManager" class.
After uploading the file, it returns an absolute URI as a string. You can save this URI into your Database according to your project’s requirement.
  1. public string UploadFile(HttpPostedFileBase FileToUpload)  
  2. {  
  3.     string AbsoluteUri;  
  4.     // Check HttpPostedFileBase is null or not  
  5.     if (FileToUpload == null || FileToUpload.ContentLength == 0)  
  6.         return null;  
  7.     try  
  8.     {  
  9.         string FileName = Path.GetFileName(FileToUpload.FileName);  
  10.         CloudBlockBlob blockBlob;  
  11.         // Create a block blob  
  12.         blockBlob = blobContainer.GetBlockBlobReference(FileName);  
  13.         // Set the object's content type  
  14.         blockBlob.Properties.ContentType = FileToUpload.ContentType;  
  15.         // upload to blob  
  16.         blockBlob.UploadFromStream(FileToUpload.InputStream);  
  17.   
  18.         // get file uri  
  19.         AbsoluteUri = blockBlob.Uri.AbsoluteUri;  
  20.     }  
  21.     catch (Exception ExceptionObj)  
  22.     {  
  23.         throw ExceptionObj;  
  24.     }  
  25.     return AbsoluteUri;  
  26. }  
Step 5
As same, add another public method to get all blob/files into "BlobManager" class.
  1. public List<string> BlobList()  
  2. {  
  3.     List<string> _blobList = new List<string>();  
  4.     foreach (IListBlobItem item in blobContainer.ListBlobs())  
  5.     {  
  6.         if (item.GetType() == typeof(CloudBlockBlob))  
  7.         {  
  8.             CloudBlockBlob _blobpage = (CloudBlockBlob)item;  
  9.             _blobList.Add(_blobpage.Uri.AbsoluteUri.ToString());  
  10.         }  
  11.     }  
  12.     return _blobList;  
  13. }  
Step 6
Add another public method to Delete blob/file into "BlobManager" class.
  1. public bool DeleteBlob(string AbsoluteUri)  
  2. {  
  3.     try  
  4.     {  
  5.         Uri uriObj = new Uri(AbsoluteUri);  
  6.         string BlobName = Path.GetFileName(uriObj.LocalPath);  
  7.   
  8.         // get block blob refarence  
  9.         CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(BlobName);  
  10.   
  11.         // delete blob from container      
  12.         blockBlob.Delete();  
  13.         return true;  
  14.     }  
  15.     catch (Exception ExceptionObj)  
  16.     {  
  17.         throw ExceptionObj;  
  18.     }  
  19. }  
Step 7 - File upload screen
Add a Controller named "Home". There will be a default Index Action Result. 
  1. public ActionResult Index(string id)  
  2. {      
  3.     return View();  
  4. }  
Then right-click on Index and add empty View for file upload screen.
  1. @using (Html.BeginForm("Index""Home", FormMethod.Post, new { enctype = "multipart/form-data" }))  
  2. {  
  3.     <fieldset>  
  4.         <legend>Upload File</legend>  
  5.         <ol>  
  6.             <li>  
  7.                 <label style="margin-right:15px;">Select file </label>  
  8.                 <input type="file" name="FilePath" value="" />  
  9.             </li>  
  10.         </ol>  
  11.         <input type="submit" value="Submit" />  
  12.     </fieldset>  
  13. }  
Write an HttpPost Action Result into Home Controller for submit the data.
Note: according to my code, if we select different file with the same name, it will replace the previous Blob. To avoid this problem you can set the file name.
  1. [HttpPost]  
  2. public ActionResult Index(HttpPostedFileBase uploadFile)  
  3. {  
  4.     foreach (string file in Request.Files)  
  5.     {  
  6.         uploadFile = Request.Files[file];  
  7.     }  
  8.     // Container Name - picture  
  9.     BlobManager BlobManagerObj = new BlobManager("picture");  
  10.     string FileAbsoluteUri = BlobManagerObj.UploadFile(uploadFile);  
  11.   
  12.     return RedirectToAction("Get");  
  13. }  
Step 8 - View and Delete
Add another Action Result into Home Controller. Where we can get all Blobs/Files from Azure Storage.
  1. public ActionResult Get()  
  2. {  
  3.     // Container Name - picture  
  4.     BlobManager BlobManagerObj = new BlobManager("picture");  
  5.     List<string> fileList = BlobManagerObj.BlobList();  
  6.     return View(fileList);  
  7. }  
The view of Get Action Result looks like this.
  1. @model List<string>  
  2. <table border="1">  
  3. <thead>  
  4.     <tr>  
  5.         <th>Picture</th>  
  6.         <th>Action</th>      
  7.     </tr>  
  8. </thead>  
  9. <tbody>  
  10.     @foreach (string SingleObj in Model)  
  11.     {  
  12.         <tr>  
  13.             <td>  
  14.                 <img src="@SingleObj" alt="@SingleObj"  
  15.                      style="height:100px; width: auto;" />  
  16.             </td>  
  17.             <td>                              
  18.                 <span>           
  19.                     @Html.ActionLink("Delete Picture""Delete","Home"new { uri = SingleObj }, new { })
  20.                 </span>                              
  21.             </td>  
  22.         </tr>  
  23.     }   
  24. </tbody>  
  25. </table>  
Add Delete action result into the Home controller.
  1. public ActionResult Delete(string uri)  
  2. {  
  3.     // Container Name - picture  
  4.     BlobManager BlobManagerObj = new BlobManager("picture");  
  5.     BlobManagerObj.DeleteBlob(uri);  
  6.     return RedirectToAction("Get");  
  7. }  
Exception Handling
You can handle the error by Storage Exception class.

No comments:

Post a Comment

Lab 09: Publish and subscribe to Event Grid events

  Microsoft Azure user interface Given the dynamic nature of Microsoft cloud tools, you might experience Azure UI changes that occur after t...