Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

One of the main components of the Digital transformation journey is storing and managing files and documents securely. Most of the applications require some features related to file upload and managing. We generally look for secure, durable, scalable, and high availability. Moreover, storing documents requires high storage space and a highly secure platform.

Uploading files or attachments is one of the common requirements for any application. Azure storage is one of the most efficient cloud storage with all the necessary features, securities, and compliance.

Azure Storage, a platform owned by Microsoft, is a contemporary cloud storage solution for almost every case scenario that is highly secure, scalable, durable, and easy to manage.

In this article, we will learn about Azure Storage and its data services. Additionally, we will create an azure storage data service with an example of Azure Blobs. Furthermore, we will upload, delete, and view files to Azure Blobs with Blazor application in .NET 7. The outline of this article are follows:

  • What is Azure Storage
  • What are the Azure Storage data services?
  • How to create an Azure Storage Account?
  • .NET Generally available
  • What is a Blazor Web App?
  • Create a Blazor Web App with .NET 7
  • Upload, delete and view files in Azure Blobs using a Blazor App in .NET 7

You can find a complete Solution on GitHub, Click Here.

Azure Storage

Azure Storage is a modern cloud storage solution owned by Microsoft, for almost every data storage scenario that is highly secure, scalable, durable, and easy to manage. It is well managed for hardware, updates, critical issues, high availability and is accessible from any part of the globe. Furthermore, the Azure UI is user-friendly, and we can create the services/objects effortlessly with all the configuration features. Additionally, Azure Storage provides all the necessary client libraries/SDK in .NET, Python, JavaScript, Java C++, PHP, Node.js, Ruby, Go, therefore developers can simply implement in their applications using the programming language of their choice. We can even access the storage objects via HTTP, HTTPS or REST API. Azure CLI or Azure PowerShell can be used by IT professionals to create scripts for those services and configuration tasks.

Let’s discuss Azure Storage Data Services.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Azure Storage Data Services

Azure storage consists of 5 data services, as portrayed in the above diagram.

Azure Blob Storage

Azure Blob Storage is a type of Azure Storage for storing massively scalable objects that are, particularly unstructured data such as text or binary data. It is used to store and access those unstructured data at a massive scale of block blobs. You can access the blob files via any applications using client libraries for multiple programming languages like .NET, Python, Java, Node.js, Ruby and PHP. Furthermore, we can use HTTP service access globally with secure access.

Scenarios to Use Azure Blob Storage

  • Storing files and document form various applications
  • Storing large file
  • Streaming video and audio files
  • Accessing files and images from browser
  • Storing file for backup, archiving, disaster recovery
  • Access file from anywhere globally via HTTP service
  • Distributed access to files and documents
  • Secure Access

​Azure Files

Azure Files Service provides a fully managed serverless file sharing option in the cloud via the industry-standard SMB and NFS protocols. Azure files enables us to build a truly hybrid file sharing environment from anywhere by mounting it concurrently from on premises and cloud.  

​To know more details: https://azure.microsoft.com/en-us/products/storage/files/

Azure Tables

This storage table is used for storing large amounts of non-relational structured or semi-structured data, i.e. NoSQL key-value for speedy development. This is highly efficient for applications that require flexible data schema and massive data in the cloud.

https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-overview

Azure Queues

This storage service is used for storing and queuing a large number of messages that can be accessed from any part of the globe via authenticated HTTP service calls. ​The Azure Queue storage provides messaging among the applications in the cloud and can be used in any programming language.  

https://learn.microsoft.com/en-us/azure/storage/queues/storage-queues-introduction

Know more about other storage services in more detail.

https://learn.microsoft.com/en-us/azure/storage/common/storage-introduction

In this write-up, we will learn to use azure storage to upload, view and delete files using Blazor Web Apps. We will upload and view files in Azure Storage using Blazor web app with .NET 7.

Let’s commence :) .

Prerequisites

  • Visual Studio 2022
  • .NET 7
  • Azure Subscription (You can create trial subscription)
  • C# Knowledge

We will use Blazer Server with .NET 7 and Azure Blob Storage.

Create Azure Storage Account

Azure storage account provides a unique namespace in the cloud for our azure storage that contains all the azure data storage components including Blob storage, Azure Files, Azure Tables, Azure Queues, and disks and can be accessible through authenticate HTTP(S) calls.

https://learn.microsoft.com/en-us/azure/storage/common/storage-account-overview

We will login to the Azure portal and search for a Storage Account.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Click Create for Storage Account.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We provide basic inputs for the storage account. 

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Choose your Subscription, Resource Group, Storage Account Name, Performance and Redundancy.

You can choose the nearest region from your location. Furthermore, we will determine the premium performance block blobs, file shares, or page blobs for the storage account.

Importantly, the data of the storage account is always duplicated to safeguard high availability and durability. We can decide redundancy of our choice. 

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

For this article, I will go with low-cost option – Locally-redundant storage LRS.

Next, we will complete the advance option as portrayed.

Security Section

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Data Lake Storage Gen2

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Blog Storage and Azure Files

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Next, we will move to the networking section.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Similarly, we will provide the data projection settings.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Encryption section

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Add your tags, review, and then create the storage account.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

It will take a few seconds to create the storage account.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Finally, the storage account is created as shown below.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Add Container

We will add a container for uploading our files. 

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Now we are ready to use this container of this Azure Storage account in Blazor Application. However, we need access keys or connection strings to upload files, which can be Azure Blade Access Keys as shown below.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We will be using this connection string in our Blazor Application to upload and delete files in Azure Blob Storage.

.NET 7 SDK

We can use any version of Visual Studio 2022, and we can download from this link. You can use the community version, which is free. Additionally, you can download .NET 7 SDK for free from this official site. In my case, I am using Visual Studio 2022 Professional, however, the steps and interfaces are the same for other versions.

Let’s commence.

We will start with the installation .NET 7 SDK for Windows. 

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Create a Web App with Blazor Server

Blazor server runs as an implementation of server side as a part of ASP.NET core app where UI events, button clicks, UI updates and interactions are communicated over SignalR connection. In this approach, the UI is generated on a web server and is transmitted to the visitor’s browser upon request. This two-way interaction occurs using SignalR and a web sockets connection. Any change in DOM content is generated from web server and update in automatically via SignalR with Blazor Server framework. This Blazor type has direct access to server and network resources since app is executed in server side. Let’s open a Visual Studio and create a new project. We will use the Blazor Server App project template.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We provide a project name and location for the solution.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

On the next screen, we will get options to choose .Net framework, Authentication type and a couple options for the project.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

After installation of .NET 7 SDK, we will have an option to choose .NET 7 in the framework. We will select the .NET 7 framework and proceed. To keep it simple, we will keep other options default.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We have successfully created a Blazor server web application with .NET 7. We will build and run the solution.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

This is how we can create a Blazor server app.

Upload and Delete Files in Azure Blob Storage Using Blazor App with .NET 7

In this section, I will write a complete project to upload and delete files in Azure Blob Storage using Blazor app in the above solution.

Firstly, we will a NuGet package named Azure.Storage.Blobs as shown below.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We will begin by creating a service class for Azure Blob Storage under a folder name Services. We will add an IBlobStorageService named interface class as shown. 

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Define an upload and delete method of the file as shown below.

Code for IBlobStorageService.cs

namespace RijsatFileUploadAzureStorage.Services;
public interface IBlobStorageService
{
    Task<string> UploadFileToBlobAsync(string strFileName, string contecntType, Stream fileStream);
    Task<bool> DeleteFileToBlobAsync(string strFileName);
}

Again, add a BlobStorageService named implementation class for the above interface under the same services folder.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

The structure will be as shown below.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Add a constructor and inject application Configuration.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Code

private readonly IConfiguration _configuration;
private readonly ILogger<BlobStorageService> _logger;
public BlobStorageService(IConfiguration configuration, ILogger<BlobStorageService> logger)
{
        _configuration = configuration;   
        _logger = logger;
}

We will add the connection sting of Storage account into appsetting.json as shown below:

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Likewise, we use this connection string in our BlobStorageService service class.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We also define the container for this blob storage. Our container name is rijsatdemo which we created during the storage account.

Function for File Upload

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Please the references as shown.

Code for Upload Function

public async Task<string> UploadFileToBlobAsync(string strFileName, string contecntType, Stream fileStream)
{
    try
    {
        var container = new BlobContainerClient(blobStorageconnection, blobContainerName);
        var createResponse = await container.CreateIfNotExistsAsync();
        if (createResponse != null && createResponse.GetRawResponse().Status == 201)
            await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
        var blob = container.GetBlobClient(strFileName);
        await blob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
        await blob.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = contecntType });
        var urlString = blob.Uri.ToString();
        return urlString;
    }
    catch (Exception ex)
    {
        _logger?.LogError(ex.ToString());
        throw;
    }
}

Similarly, the code for deleting file method.

public async Task<bool> DeleteFileToBlobAsync(string strFileName)
{
    try
    {
        var container = new BlobContainerClient(blobStorageconnection, blobContainerName);
        var createResponse = await container.CreateIfNotExistsAsync();
        if (createResponse != null && createResponse.GetRawResponse().Status == 201)
            await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
        var blob = container.GetBlobClient(strFileName);
        await blob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
        return true;
    }
    catch (Exception ex )
    {
        _logger?.LogError(ex.ToString());
        throw;
    }
}

Overall, the BlobStorageService class be as shown below.

using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Extensions.Logging;
using System.Reflection.Metadata.Ecma335;

namespace RijsatFileUploadAzureStorage.Services;
public class BlobStorageService : IBlobStorageService
{
    private readonly IConfiguration _configuration;
    private readonly ILogger<BlobStorageService> _logger;
    string blobStorageconnection = string.Empty;
    private string blobContainerName = "rijsatdemo";
    public BlobStorageService(IConfiguration configuration, ILogger<BlobStorageService> logger)
    {
        _configuration = configuration;   
        _logger = logger;
        blobStorageconnection = _configuration.GetConnectionString("AzureStorageAccount");
    }
    public async Task<string> UploadFileToBlobAsync(string strFileName, string contecntType, Stream fileStream)
    {
        try
        {
            var container = new BlobContainerClient(blobStorageconnection, blobContainerName);
            var createResponse = await container.CreateIfNotExistsAsync();
            if (createResponse != null && createResponse.GetRawResponse().Status == 201)
                await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
            var blob = container.GetBlobClient(strFileName);
            await blob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
            await blob.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = contecntType });
            var urlString = blob.Uri.ToString();
            return urlString;
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex.ToString());
            throw;
        }
    }
    public async Task<bool> DeleteFileToBlobAsync(string strFileName)
    {
        try
        {
            var container = new BlobContainerClient(blobStorageconnection, blobContainerName);
            var createResponse = await container.CreateIfNotExistsAsync();
            if (createResponse != null && createResponse.GetRawResponse().Status == 201)
                await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
            var blob = container.GetBlobClient(strFileName);
            await blob.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
            return true;
        }
        catch (Exception ex )
        {
            _logger?.LogError(ex.ToString());
            throw;
        }
    }
}

We will add a dependency injection service to the container in the program.cs file.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

builder.Services.AddScoped<IBlobStorageService, BlobStorageService>();

Add a view model or Data transfer object of file upload into services folder as shown.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Code for the FileUploadViewModel.cs

namespace RijsatFileUploadAzureStorage.Services.Dto
{
    public class FileUploadViewModel
    {
        public string FileName { get; set; }
        public string FileStorageUrl { get; set; }
        public string ContentType { get; set; }
    }
}

Now we will move to the Blazor Component for the uploading section in the Index.razor component file.

Add a file upload section into Index component. Replace Index with below code.

<h4>File Upload (Azure Blob Storage)</h4>
<div class="row">
    <div class="col-sm-6">
        <label>
            <InputFile class="form-control" disabled="@fileLoading" OnChange="@OnInputFileChange" single />
        </label>
        @if (fileLoading)
        {
            <i class="fa fa-refresh"></i> <span>Loading...</span>
        }
    </div>
    <div class="col-sm-2">
        <button type="button" disabled="@fileLoading" class="btn btn-primary" @onclick="OnUploadSubmit">
            Upload File
        </button>
    </div>
</div>

Then, I will add a table to show the list of uploaded files.

<div class="row">
    @if (fileUploadViewModels.Count > 0)
    {
        <table class="table table-responsive table-bordered">
            <thead class="text-primary">
                <tr>
                    <th>File</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var attachment in fileUploadViewModels)
                {

                    <tr>
                        <td>
                            <a class="text-primary"><i class="fa-solid fa-paperclip"></i> @attachment.FileName</a>
                        </td>                      
                       
                            <td>
                            <span class="oi oi-delete" aria-hidden="true" @onclick="() => OnFileDeleteClick(attachment)"></span>
                            </td>
                    </tr>
                }
            </tbody>
        </table>
    }
    else
    {
        <div class="alert alert-info">
            <strong>No Files!</strong>
        </div>
    }
</div>

We will add the code part for uploading and deleting in index.razor component.

@code {
    private string warninngMessage = "";
    private string displayMessage = "";
    private List<IBrowserFile> loadedFiles = new();
    private long maxFileSize = 1024 * 15;
    private int maxAllowedFiles = 3;
    private bool fileLoading;
    string Message = "No file(s) selected";
    IReadOnlyList<IBrowserFile> selectedFiles;
    private List<FileUploadViewModel> fileUploadViewModels = new();
    private void OnInputFileChange(InputFileChangeEventArgs e)
    {
        selectedFiles = e.GetMultipleFiles();
        Message = $"{selectedFiles.Count} file(s) selected";
        this.StateHasChanged();
    }
    private async void OnUploadSubmit()
    {
        fileLoading = true;
        foreach (var file in selectedFiles)
        {
            try
            {
                var trustedFileNameForFileStorage = file.Name;
                var blobUrl = await blobStorageService.UploadFileToBlobAsync(trustedFileNameForFileStorage, file.ContentType, file.OpenReadStream(20971520));
                if (blobUrl != null)
                {
                    FileUploadViewModel fileUploadViewModel = new FileUploadViewModel()
                        {
                            FileName = trustedFileNameForFileStorage,
                            FileStorageUrl = blobUrl,
                            ContentType = file.ContentType,
                        };

                    fileUploadViewModels.Add(fileUploadViewModel);
                    displayMessage = trustedFileNameForFileStorage + " Uploaded!!";
                }
                else
                    warninngMessage = "File Upload failed, Please try again!!";

            }
            catch (Exception ex)
            {
                warninngMessage = "File Upload failed, Please try again!!";
            }
        }

        fileLoading = false;
        this.StateHasChanged();
    }

    private async void OnFileDeleteClick(FileUploadViewModel attachment)
    {
        try
        {
            var deleteResponse = await blobStorageService.DeleteFileToBlobAsync(attachment.FileName);
            if (deleteResponse)
            {
                fileUploadViewModels.Remove(attachment);
                displayMessage = attachment.FileName + " Deleted!!";
            }
            
        }
        catch (Exception)
        {
            warninngMessage = "Something went wrong! Please try again.";
        }
        this.StateHasChanged();
    }

}

In the above code, we have OnUploadSubmit() and OnFileDeleteClick().

Complete Index.razor component code.

@page "/"
@using RijsatFileUploadAzureStorage.Services;
@using RijsatFileUploadAzureStorage.Services.Dto;
@inject IBlobStorageService blobStorageService

<PageTitle>Index</PageTitle>
@if (warninngMessage.Length > 0)
{
    <div class="alert alert-warning">
        <strong>Warning!</strong> @warninngMessage.
    </div>
}

<h4>File Upload (Azure Blob Storage)</h4>
<div class="row">
    <div class="col-sm-6">
        <label>
            <InputFile class="form-control" disabled="@fileLoading" OnChange="@OnInputFileChange" single />
        </label>
        @if (fileLoading)
        {
            <i class="fa fa-refresh"></i> <span>Loading...</span>
        }
    </div>
    <div class="col-sm-2">
        <button type="button" disabled="@fileLoading" class="btn btn-primary" @onclick="OnUploadSubmit">
            Upload File
        </button>
    </div>
</div>
@if (displayMessage.Length > 0)
{
    <div class="alert alert-success">
        <strong>Success!</strong> @displayMessage.
    </div>
}
<br />
<div class="row">
    @if (fileUploadViewModels.Count > 0)
    {
        <table class="table table-responsive table-bordered">
            <thead class="text-primary">
                <tr>
                    <th>File</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var attachment in fileUploadViewModels)
                {

                    <tr>
                        <td>
                            <a class="text-primary"><i class="fa-solid fa-paperclip"></i> @attachment.FileName</a>
                        </td>                      
                       
                            <td>
                            <span class="oi oi-delete" aria-hidden="true" @onclick="() => OnFileDeleteClick(attachment)"></span>
                            </td>
                    </tr>
                }
            </tbody>
        </table>
    }
    else
    {
        <div class="alert alert-info">
            <strong>No Files!</strong>
        </div>
    }
</div>

@code {
    private string warninngMessage = "";
    private string displayMessage = "";
    private List<IBrowserFile> loadedFiles = new();
    private long maxFileSize = 1024 * 15;
    private int maxAllowedFiles = 3;
    private bool fileLoading;
    string Message = "No file(s) selected";
    IReadOnlyList<IBrowserFile> selectedFiles;
    private List<FileUploadViewModel> fileUploadViewModels = new();
    private void OnInputFileChange(InputFileChangeEventArgs e)
    {
        selectedFiles = e.GetMultipleFiles();
        Message = $"{selectedFiles.Count} file(s) selected";
        this.StateHasChanged();
    }
    private async void OnUploadSubmit()
    {
        fileLoading = true;
        foreach (var file in selectedFiles)
        {
            try
            {
                var trustedFileNameForFileStorage = file.Name;
                var blobUrl = await blobStorageService.UploadFileToBlobAsync(trustedFileNameForFileStorage, file.ContentType, file.OpenReadStream(20971520));
                if (blobUrl != null)
                {
                    FileUploadViewModel fileUploadViewModel = new FileUploadViewModel()
                        {
                            FileName = trustedFileNameForFileStorage,
                            FileStorageUrl = blobUrl,
                            ContentType = file.ContentType,
                        };

                    fileUploadViewModels.Add(fileUploadViewModel);
                    displayMessage = trustedFileNameForFileStorage + " Uploaded!!";
                }
                else
                    warninngMessage = "File Upload failed, Please try again!!";

            }
            catch (Exception ex)
            {
                warninngMessage = "File Upload failed, Please try again!!";
            }
        }

        fileLoading = false;
        this.StateHasChanged();
    }

    private async void OnFileDeleteClick(FileUploadViewModel attachment)
    {
        try
        {
            var deleteResponse = await blobStorageService.DeleteFileToBlobAsync(attachment.FileName);
            if (deleteResponse)
            {
                fileUploadViewModels.Remove(attachment);
                displayMessage = attachment.FileName + " Deleted!!";
            }
            
        }
        catch (Exception)
        {
            warninngMessage = "Something went wrong! Please try again.";
        }
        this.StateHasChanged();
    }

}

Let’s build and run the solution.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Uploading File into the Azure Blob Storage.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

Let me show the uploaded file into Azure Blob from Azure Portal.

Go to the container and open it (rijsatdemo).

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

We can see the file in the Azure Blob container. We have successfully uploaded the file into Azure Blob Storage using the Blazor Server with .NET 7.

Likewise, we can delete the file using above the code as demonstrated.

Upload and Delete Files in Azure Blob Storage Using Blazor Apps With .NET 7

This is how we can upload and delete files in Azure Blob Storage from a Blazor App with .NET 7.

You can find a complete Solution on GitHub, Click Here.

Conclusion

In this article, I have done a complete solution to upload and delete files in Azure Blob Storage from Blazor Application with .NET 7. Furthermore, I have demonstrated how to create an Azure Storage Account and a container for uploading files and documents. Then again, I have built a Blazor Server web application with .NET 7. At last, I did a complete solution to upload and delete files in Azure Blob Storage with code and showed an example. 


Similar Articles