DEV Community

Cover image for How To Upload and Delete files in Azure Blob Storage Using Blazor Apps With .NET 7
Rijwan Ansari
Rijwan Ansari

Posted on

How To 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. https://github.com/rijwanansari/RijsatFileUploadAzureStorage

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

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 amount of non-relational structured or semi-structured data, i.e. NoSQL key-value for speedy development. This is highly efficient for the 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

Click Create for Storage Account.

Upload and Delete files in Azure Blob Storage

We provide basic inputs for the storage account.

Upload and Delete files in Azure Blob Storage

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

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

Next, we will complete the advance options as portrayed.

Security Section

Upload and Delete files in Azure Blob Storage

Data Lake Storage Gen2

Upload and Delete files in Azure Blob Storage

Blog Storage and Azure Files

Upload and Delete files in Azure Blob Storage

Next, we will move to the networking section.

Upload and Delete files in Azure Blob Storage

Similarly, we will provide the data projection settings.

Upload and Delete files in Azure Blob Storage

Upload and Delete files in Azure Blob Storage

Encryption section

Upload and Delete files in Azure Blob Storage

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

Upload and Delete files in Azure Blob Storage

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

Upload and Delete files in Azure Blob Storage

Finally, the storage account is created as shown below.

Upload and Delete files in Azure Blob Storage

Add Container

We will a container for uploading our files.

Upload and Delete files in Azure Blob Storage

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

.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

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.

To know more about Blazor Web Development, click here.

To learn to develop a Blazor Application, click here.

Upload and Delete files in Azure Blob Storage

We will provide a project name and location for the solution.

Upload and Delete files in Azure Blob Storage

​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

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

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

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

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

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);
}
Enter fullscreen mode Exit fullscreen mode

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

Upload and Delete files in Azure Blob Storage

The structure will be as shown below.

Upload and Delete files in Azure Blob Storage

Add a constructor and inject application Configuration.

Upload and Delete files in Azure Blob Storage

Code

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

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

Upload and Delete files in Azure Blob Storage

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

Upload and Delete files in Azure Blob Storage

We will also define our 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

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;
        }
    }
Enter fullscreen mode Exit fullscreen mode

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;
        }
    }
Enter fullscreen mode Exit fullscreen mode

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;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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

Upload and Delete files in Azure Blob Storage

builder.Services.AddScoped<IBlobStorageService, BlobStorageService>();
Enter fullscreen mode Exit fullscreen mode

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

Upload and Delete files in Azure Blob Storage

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; }
    }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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();
    }

}
Enter fullscreen mode Exit fullscreen mode

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();
    }

}
Enter fullscreen mode Exit fullscreen mode

Let’s build and run the solution.

Upload and Delete files in Azure Blob Storage

Uploading File into the Azure Blob Storage.

Upload and Delete files in Azure Blob Storage

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

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

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.
Reference:
https://rijsat.com/2023/01/11/upload-and-delete-files-in-azure-blob-storage-using-blazor-apps-with-net-7/

Top comments (0)