How to handle file uploads with Blazor and Azure Blob Storage - part 3: large files
How to handle file uploads with Blazor and Azure Blob Storage - part 3: large files

How to handle file uploads with Blazor and Azure Blob Storage - part 3: large files

2021, Jun 20    

Hi All and welcome back to another episode of the Series “How to handle file uploads with Blazor and Azure Blob Storage”!

The last time we went down the rabbit hole and wrote the server-side code responsible of storing our images in am Azure Blob Container. The “problem” with that sample is that we are pre-loading the image in order to show a preview to the user. This prevents us from sending a Stream to our server and leverage the UploadBlobAsync() method on the BlobContainerClient instance.

This might even be fine for small files, but what if we’re dealing with really large uploads and we don’t even need a preview?

And indeed, Edoardo even asked me that on LinkedIn, so let’s figure it out!

I’ve made few changes to the repository on GitHub and added a new box:

Blazor file uploads

As you can see, you can customize the maximum allowed size in MB, select a file and upload it. This time no preview box. But what’s the difference? It’s subtle and starts in the OnSubmit() method:

private async Task OnSubmit()
{
    var allowedSize = (long)_formModel.MaxFileSize * 1000000;
    using var stream = _formModel.File.OpenReadStream(allowedSize);

    var command = new Commands.UploadFile(Guid.NewGuid(), stream);
    await this.Mediator.Publish(command);
}

It all lies in the OpenReadStream call: by default the file size is capped at 500 KB, but it can be customized by passing the desired amount.

At this point all we have to do is to send the resulting Stream instance to the Command Handler and we’re done, at least on the client.

On the server now we don’t have to create a MemoryStream anymore, but we can call directly UploadBlobAsync():

public async Task Handle(UploadFile command, CancellationToken cancellationToken)
{
    var blobName = $"file_{command.FileId}.jpg";
    var blobContainer = await _blobFactory.CreateContainerAsync("uploaded-files", cancellationToken);
    await blobContainer.DeleteBlobIfExistsAsync(blobName, cancellationToken: cancellationToken);

    if (command.FileStream is not null)
    {
        await blobContainer.UploadBlobAsync(blobName, command.FileStream, cancellationToken);
    }
}

That’s it!

This way you can easily handle uploads of very large files with Blazor. For those interested, if you fire up your browser’s developer tools, you might also be able to see the network calls on the websocket:

Blazor websocket calls

Ciao!