Blazor Web Assembly with .NET 6: Uploading File to Azure BLOB Storage

In this article, we will implement the File Upload to Azure BLOB using the Blazor Web Assembly application. In one of my earlier articles, I have explained the File Upload to Azure BLOB using Node.js. You can read about it from this link.  After publishing that article, I have received feedback from some of my students that, I should also explain the File Upload steps using Blazor Web Assembly assembly, and then I have decided to work on it. 

I have already published some articles on Blazor. You can read them from the following links

1. ASP.NET Core 5 and Blazor Web Assembly Apps: Token Based Authentication in ASP.NET Core 5 APIs and Authenticating it using Blazor WebAssembly Apps

2. Blazor WebAssembly: Uploading Image to ASP.NET Core 5 API from Blazor WebAssembly Project

3. ASP.NET Core 5.0: Create API with Swagger(OpenAPI) Specifications and Consuming it in Blazor Web Assembly Project using Connected Service

4. gRPC service in .NET 5: Consuming gRPC Service in Blazor WebAssembly Application

5. Blazor: JavaScript Interop Accessing JavaScript Functions in Blazor Components

6. Passing Data Across Blazor Components

7. Creating Blazor Server App for Performing CRUD Operations using EntityFramework Core

8. Blazor WebAssembly: Using C3.js to Create Charts in Blazor WebAssembly Application

In this article, the Blazor Web Assembly will access the Azure BLOB storage using the Security Access Signature (SAS) Token. 

What is SAS Token?

A Shared Access Signature (SAS) is a URI that grants restricted access rights to Azure Storage resources. A shared access signature can be provided to clients who should not be trusted with the storage account key but whom we wish to delegate access to certain storage account resources. By distributing a shared access signature URI to these clients, we grant them access to a resource for a specified period of time. 

Technically, it is a query string that includes all of the information required to authenticate the SAS, as well as to specify the service, resource, and permissions available for access and the time interval over which the signature is valid. 

The Implementation

In the previous article, I have already explained the steps for creating Azure Resource Group and the Storage Account with BLOB container.

The SAS Token can be generated using the Shared access signature link of the storage account as shown in Figure 1 and Figure 2



Figure 1: Selecting Resource Types for generating SAS  

Figure 1 shows that to generate SAS we need to select the Services e.g. Blob, resource type e.g. Container, permissions to read, write, etc. By using these settings we will make sure that we are providing restricted access to clients to access storage resources. Figure 2, shows some other important settings e.g. expiry time, protocols, etc.



Figure 2: The settings for expiry time for SAS token     

The Start and expiry date/time will make sure that the clients whom we have provided this SAS token will be having time-bound access to the Storage resources. Figure 3, shows the UI for SAS generation. 



Figure 3: Generation of SAS

 As shown in Figure 3, we need to select the Access Key of the Storage Account and click on the Generate SAS and connection string button. This will generate connection string, SAS token, and URL for various resource types e.g. BLOB, Table, Queue, etc. Copy the SAS token, we will need it in the code. 

Step 1: Open Visual Studio 2022 (Community or Enterprise) and create a new Blazor Web Assembly Application targetted to .NET 6. Name this application as Blazor_wasm_blobupload.

Step 2: In this project add a NuGet Package named Azure.Storage.Blobs. This package provides access to Azure BLOB Storage.  In the project, add a new Razor Component in the Pages folder. Name this component as AzureBlobUploadFile.razor. In this component add the code as shown in listing 1


@page "/uploadblob"

@using System.ComponentModel.DataAnnotations
@using System.IO
@using System.Linq
@using System.Threading
@using Azure
@using Azure.Storage
@using Azure.Storage.Blobs
@using Azure.Storage.Blobs.Models

<h3>Azure Blob Upload File</h3>

<div class="container">
    <label>Select the File to be uploaded:</label>
    <InputFile id="browseFile" OnChange="@OnFileSelectionChange"></InputFile>
    <hr/>
     
    <div class="progress">
    <div class="progress-bar bg-info" role="progressbar" aria-valuenow="@progressBar"
                     aria-valuemin="0" aria-valuemax="100"
 style="@($"width: { progressBar }%")">
    <span class="sr-only">@progressBar</span>
  </div>
</div>
    <hr />
    <div class="container">
        <strong>
            @statusMessage
        </strong>
    </div>

</div>
@code {
    private int maxFileSize = 1024 * 1024 * 20;
    private string statusMessage = String.Empty;
    private bool showProgressBar = false;
    private string progressBar = String.Empty;

    private async Task OnFileSelectionChange(InputFileChangeEventArgs e)
    {
        try
        {
            statusMessage = String.Empty;
            // 1. Select the file
            var selectedFile = e.File;
            // 2. The URL for the BLOB, the file that will  be created into the container
            var azureBlobUri = new Uri
($"https://[STORAGE-ACCOUNT-NAME].blob.core.windows.net/[CONTAINER-NAME]/{selectedFile.Name}");
            // 3. Authenticate to the Azure Service using teh SAS
            AzureSasCredential sasCredentials = new AzureSasCredential
            ("[SAS-TOKEN-COPIED-FROM-THE-PORTAL]");
            // 4. The BLOB Client to access the BLOB to upload the file
            BlobClient blobClient = new BlobClient(azureBlobUri, sasCredentials, 
                        new BlobClientOptions());

            // 5. Upoload the file
            var res = await blobClient.UploadAsync(selectedFile.OpenReadStream(maxFileSize),
            new BlobUploadOptions
                {
                    // 5.1. define HTTP Header Content Type 
                    HttpHeaders = new BlobHttpHeaders { ContentType =
                         selectedFile.ContentType },
                    // 5.2. THe Transfer behavior with the transfer size
                    TransferOptions = new StorageTransferOptions
                    {
                        InitialTransferSize = 1024 * 1024
                    },
                    // 5.3. The File Progress
                    ProgressHandler = new Progress<long>((progress) =>
                    {
                        progressBar = (100.0 * progress / selectedFile.Size).ToString("0");

                    })
                });
            statusMessage = "File Uploaded Successfully......";
        }
        catch (Exception ex)
        {
            statusMessage = ex.Message;
        }


    }
}

Listing 1: The File Upload code to BLOB

As shown in Listing 1, the OnFileSelectionChange() method is bound to the InputFile standard component provider by the Blazor. The code in Listing 1 has the following specifications (Note: Following numbering matches with the comments applied on code)

  1. Accept the selected file using InputFile Component
  2. Define a BLBL URI, this will consist of the BLOB URL based on the Storage account name and the Container name in which the file will be uploaded
  3. Using AzureSasCredential class will be used to authenticate against the Azure Service using SAS Token Credentials.
  4. Using BlobClient class connect to the BLOB so that the File Uploading operations can be started.
  5. The file can be uploaded using UploadAsync() method
    1. The HTTP Headers Must be set with MIME type so that we will be informing to HTTP protocol about the file type e.g. png, jpeg, pdf, etc.
    2.  Using TransferOptions, we define the parallel transfer behavior
    3. Using ProgressHandler, we check the file upload progress, which we have used to define the progress bar.     

Step 3: Modify the NavMenu.razor file in the Shared folder so that we can show the navigation link for the component which we have created for file upload. Listing 2 show the code for the Navigation link


 <div class="nav-item px-3">
            <NavLink class="nav-link" href="uploadblob">
                <span class="oi oi-list-rich" aria-hidden="true"></span> File Upload to BLOB
            </NavLink>
        </div>

Listing 2: The Navigation link  

Run the application and from the home page click on the  File Upload to BLOB, the UI for file upload will be loaded, here choose the file to upload, once the file is uploaded, the result will be displayed  as shown in Figure 4



Figure 4: File Upload UI

Once the file upload is successful, you can visit back to the portal and under the BLOB Container, you can see the uploaded file.

The code this article can be downloaded from here.

Conclusion: Using the SAS Token, the Blazor Web Assembly application can directly access the Azure Storage Services for performing resource Read/Write operations based on the settings configured for accessing the resources by you for your client.  


 

Popular posts from this blog

ASP.NET Core 6: Adding Custom Middleware and Logging the Error Message in Database

ASP.NET Core 6: Downloading Files from the Server

ASP.NET Core 6: Using Role Based Security for ASP.NET Core 6 WEB API