DEV Community

loading...
Cover image for Intro to Azure Storage with .Net 5

Intro to Azure Storage with .Net 5

moe23 profile image Mohamad Lawand Updated on ・6 min read

In this article i will explaining to you how we can utilise Azure Storage specifically Blobs in our application.

You watch the full step by step video on Youtube

You also get the source code from Github:
https://github.com/mohamadlawand087/v15-AzureStorage

So what are we going to cover today:

  • What do we need to get started
  • Azure Storage basics
  • The structure of our application
  • Code

If you find this video helpful, please like, share and subscribe as it will really help the channel.

Before we start you will need to have

So what are we going to build today, we will build a sample application which will list all of the blobs that we have, we will be able to add and delete blobs as well.

Azure storage is a highly scalable service in azure allowing us to store files, images, tables, videos, unstructured data, messages and NoSql databases.

Azure storage features:

  • durable: high availability data centers managed by Microsoft
  • secure: All data is encrypted
  • scalable
  • managed
  • accessible: API and SDKs available to integrate with these services

Services that are part of storage account

  • Blob
  • File
  • Queue
  • Table

Blob Storage:

Azure Blob storage is a service for storing large amounts of unstructured object data, such as text or binary data. You can use Blob storage to expose data publicly to the world, or to store application data privately. Common uses of Blob storage include:

  • Serving images or documents directly to a browser
  • Storing files for distributed access
  • Streaming video and audio
  • Storing data for backup and restore, disaster recovery, and archiving
  • Storing data for analysis by an on-premises or Azure-hosted service

Structure of blob storage

Account → Container → Files

Alt Text

File Storage

Its a service that allows your to create fully managed file shares in the cloud that are accessible

via Server Message Block (SMB) and Network File Service (NFS)

It has the same structure as blob storage the main difference is that instead of only hosting files it contains folders

Alt Text

So when do you choose Blob or File storage, if you use Lift and Shift you should use File Storage other then that Blob storage is recommended due to its maturity levels.

Storage Queue

Azure Queue Storage provides cloud messaging between application components. Queue Storage delivers asynchronous messaging between application components, whether they are running in the cloud, on the desktop, on an on-premises server, or on a mobile device.

Alt Text

Its a simple messaging service which can be utilised in Azure Storage

Table Storage

Azure Table storage stores large amounts of structured data. The service is a NoSQL datastore which accepts authenticated calls from inside and outside the Azure cloud. Azure tables are ideal for storing structured, non-relational data.

It is the simplest NoSql db we can use but its also very secure and scalable, storage tables are seperated into datable and every table will contain NoSql data

Every record can be public or private depends on the configuration of the table.

Common use cases

  • Storing tables of structured data capable of serving web scale applications
  • Storing datasets
  • Quickly querying data using a clustered index
  • Accessing data using the OData protocol and LINQ queries

Alt Text

Now lets jump into coding

We will need first to create a new mvc application using the dotnet new keyword

dotnet new mvc -n "BlobSampleApp"
Enter fullscreen mode Exit fullscreen mode

Now we need to add Blob nuget package

dotnet add package Azure.Storage.Blobs --version 12.8.0
Enter fullscreen mode Exit fullscreen mode

Once the application is created we need to add a folder to the root directory of our application called Services

Inside the Services folder we need to create 2 files IBlobService and BlobService lets start with the interface

public interface IBlobService
{
      Task<string> GetBlob(string name, string containerName);
    Task<IEnumerable<string>> AllBlobs(string containerName);
    Task<bool> UploadFileBlob(string name, IFormFile file, string containerName);
    Task<bool> DeleteBlob(string name, string containerName);
}
Enter fullscreen mode Exit fullscreen mode
public class BlobService : IBlobService
{
    public Task<IEnumerable<string>> AllBlobs(string containerName)
    {
        throw new System.NotImplementedException();
    }

    public Task<bool> DeleteBlob(string name, string containerName)
    {
        throw new System.NotImplementedException();
    }

    public Task<string> GetBlob(string name, string containerName)
    {
        throw new System.NotImplementedException();
    }

    public Task<bool> UploadFileBlob(string name, IFormFile file, string containerName)
    {
        throw new System.NotImplementedException();
    }
}
Enter fullscreen mode Exit fullscreen mode

The next step is creating a Blob resource on Azure, we need to navigate in our browser to portal.azure.com

  • click on create resource
  • In the search bar type "storage account"
  • select Storage Account from the result list
  • Click on create
  • Create or select a resource group
  • Give it a name "mlyoutubedata"
  • choose a location
  • Select Standard in performance
  • Account kind StorageV2
  • Replication Locally redundant storage LRS
  • Now lets click on create and review
  • and then create

This should take few minutes to be complete, once the task is completed we need to go to the resource

  • Select containers
  • click on Add container
  • Give it a name "personal"
  • keep the access level to public (only for testing)
  • click on create

The last step is to get the keys which will allow us to communicate with our blob storage.

lets navigate to the main storage resource and click on Access keys under settings and lets copy the connection string

Now lets navigate back to our code and inside our appsettings.json lets add the following

"BlobConnection" : "xxxxxxxxxConnectionStringFromAzurexxxxxxxxxxxxx"
Enter fullscreen mode Exit fullscreen mode

Next we will need to go to our startup class and register our blob client, inside our ConfigureServicesMethod we need to add the following

// Initialising the BlobService, this will allow us to inject the blob 
// client into our service
var blobConnection = Configuration.GetValue<string>("BlobConnection");
services.AddSingleton(x => new BlobServiceClient(blobConnection));

// We need to add our own custom blob service
services.AddSingleton<IBlobService, BlobService>();
Enter fullscreen mode Exit fullscreen mode

Now lets start implementing our Service

public class BlobService : IBlobService
{
    private readonly BlobServiceClient _blobClient;

    public BlobService(BlobServiceClient blobClient)
    {
        _blobClient = blobClient;
    }

    public async Task<IEnumerable<string>> AllBlobs(string containerName)
    {
        // This will me to access data inside the personal container
        var containerClient = _blobClient.GetBlobContainerClient(containerName);
        var files = new List<string>();

        var blobs = containerClient.GetBlobsAsync();

        // We are awaiting a foreach here as the 
        // blobs are streambale objects we need to wait until they are available
        await foreach(var item in blobs)
        {
            files.Add(item.Name);
        }

        return files;
    }

    public async Task<bool> DeleteBlob(string name, string containerName)
    {
       // This will me to access data inside the personal container
        var containerClient = _blobClient.GetBlobContainerClient(containerName);
        var blobClient = containerClient.GetBlobClient(name);
        return await blobClient.DeleteIfExistsAsync(); 
    }

    public async Task<string> GetBlob(string name, string containerName)
    {
         // In order for us to get access to anything inside our blob 
        // We first need to connect to the blob container 
        // and then we need to get the container client which referes to the 
        // specific container we want to access

        // This will me to access data inside the personal container
        var containerClient = _blobClient.GetBlobContainerClient(containerName);
        var blobClient = containerClient.GetBlobClient(name);

        var str = blobClient.Uri.AbsoluteUri;

        return str;
    }

    public async Task<bool> UploadFileBlob(string name, IFormFile file, string containerName)
    {
        try
        {
            var containerClient = _blobClient.GetBlobContainerClient(containerName);

            // The idea of getting a reference to a blob client which doesnt exist 
            // is the way Azure blobs are implemented, we initiate these client 
            // and then we do checks if actually exist or not and then we can perform
            // any action we want upload, delete ...
            var blobClient = containerClient.GetBlobClient(name);
            //var blobClient1 = containerClient.GetBlobClient("1"+name);

            var httpHeaders = new BlobHttpHeaders() { 
                ContentType=file.ContentType 
            };

            var blobInfo = await blobClient.UploadAsync(file.OpenReadStream(), httpHeaders);

            if(blobInfo != null)
                return true;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }           

        return false;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now after our service is ready lets build our controller, inside our controllers folder lets create a new controller called "FilesController"

public class FilesController : Controller
{
    private readonly IBlobService _blobService;

    public FilesController(IBlobService blobService)
    {
        _blobService = blobService;
    }

    [HttpGet]
    public async Task<IActionResult> Index()
    {
        var files = await _blobService.AllBlobs("personal");
        return View(files);
    }

     [HttpGet]
    public async Task<IActionResult> ViewFile(string name)
    {
        var res = await _blobService.GetBlob(name, "personal");

        return Redirect(res);
    }

     [HttpGet]
    public async Task<IActionResult> DeleteFile(string name)
    {
        await _blobService.DeleteBlob(name, "personal");

         return RedirectToAction("Index");
    }

    [HttpGet]
    public IActionResult AddFile()
    {
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> AddFile(IFormFile file)
    {
         if (file == null || file.Length <= 0) return View();

        if (file!=null)
        {
            string fileName= Guid.NewGuid().ToString() + Path.GetExtension(file.FileName.Replace(" ",""));
            var res = await _blobService.UploadFileBlob(fileName, file, "personal");

            if(res)
                return RedirectToAction("Index");
        }
        return View();
    }  
}
Enter fullscreen mode Exit fullscreen mode

Then we need to create a folder called Files inside our Views folder, then we need to create a file called index.cshtml and update to the below

@model List<string>

<div class="row">
    <div class="col-md-12">
        <a asp-action="AddFile" asp-controller="Files" class="btn btn-success"> upload files</a>
    </div>
     <div class="col-md-12">
        <ul>
@foreach (var item in Model)
{
    <li>
        <a asp-action="ViewFile" asp-controller="Files" asp-route-name="@item" target="_blank"> @item</a> - <a asp-action="DeleteFile" asp-controller="Files" asp-route-name="@item" class="btn btn-danger"> Delete</a>
    </li>
}
</ul>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Lastly we need to create our AddFile view by adding a file called AddFile.cshtml and update the code to the below

<form class="col-xs-12" method="post" asp-action="AddFile" asp-controller="Files" enctype="multipart/form-data">

     <div class="form-group">
        <input type="file" class="form-control" name="file" />
     </div>

     <div class="form-group">
        <button type="submit" class="btn btn-primary col-xs-12">Add</button>
     </div>
  </form>
Enter fullscreen mode Exit fullscreen mode

Thank you for reading, please share and like if you find it useful

Discussion (0)

pic
Editor guide