Upload to Azure Blob from Web Api

In the earlier post, we learned how to set up docker containers for Azurite. In this post, we will continue with process and create a Web API to exposure end points to upload file to the Azure Blob and to download them.

Let’s go ahead create our Web Api. I will skip the entire project creation part, and focus on the end points and BlobService. We will begin by defining the IBlobService.

public interface IBlobService
{
    Task<Azure.Response<BlobContentInfo>> UploadFile(IFormFile file, string blobFileName, CancellationToken cancellationToken = default);
    Task<byte[]> GetFile(string blobFileName, CancellationToken cancellationToken = default);
}

The BlobService would our helper service which would communicate with the Blob on behalf of our controller. The BlobService would be exposing two methods, UploadFile and GetFile, which would be used to upload and download file from the Blob.

public class BlobService : IBlobService
{
    // TODO: Read from configuration file
    private const string ConnectionString = "connectionString";
    private const string ContainerName = "containerName";

    private readonly BlobServiceClient _blobServiceClient;
    private readonly BlobContainerClient _blobContainerClient;

    public BlobService()
    {
        _blobServiceClient = new BlobServiceClient(ConnectionString);
        _blobContainerClient = _blobServiceClient.GetBlobContainerClient(ContainerName);
    }
    public async Task<Azure.Response<BlobContentInfo>> UploadFile(IFormFile file,string blobFileName, CancellationToken cancellationToken = default)
    {
        using var memoryStream = new MemoryStream();
        file.CopyTo(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);

        await _blobContainerClient.CreateIfNotExistsAsync().ConfigureAwait(false);
        var response = await _blobContainerClient.UploadBlobAsync(blobFileName, memoryStream, cancellationToken);
        return response;
    }
}


Let us first look into the implementation of UploadFile() method. The method recieves IFormFile and blobFileName which would be used as key to identify the blob in the storage. The method reads the contents of the IFormFile and use the BlobContainerClient.UploadBlobAsync() method to upload the file.

To retrieve the file, you can use the following implementation.

public async Task<byte[]> GetFile(string blobFileName,CancellationToken cancellationToken = default)
{
    var blobClient = _blobContainerClient.GetBlobClient(blobFileName);
    var response = await blobClient.DownloadContentAsync();
    return response.Value.Content.ToArray();
}

The GetFile() method uses BlobContainerClient.GetBlobClient() to retrive the required Blob details. We then can use the DownloadContentAsync() method to download the actual file content.

Let us now proceed to define our controller and end points.

[ApiController]
[Route("api/file")]
public class FileHandlingController : ControllerBase
{
    private readonly IBlobService _blobService;
    public FileHandlingController(IBlobService blobService)
    {
        _blobService = blobService;
    }

    [HttpPost]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [Route("uploadfile")]
    public async Task<IActionResult> UploadFile([FromForm]FileInput file)
    {
        try
        {
            var response = await _blobService.UploadFile(file.File, file.Key, default).ConfigureAwait(false);
        }
        catch (RequestFailedException e)
        {
            return BadRequest($"File upload failed :{e.Message}");
        }
        
        return Ok("File uploaded successfully");
    }

    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [Route("get")]
    public async Task<ActionResult> Get(string fileName)
    {
        var response = await _blobService.GetFile(fileName).ConfigureAwait(false);
        return File(response, "application/jpg",fileName);
    }
}

As seen in the code above, the FileHandlingController uses the BlobService to upload and download the required file. That’s all we require to access Blob storage.

As you can observe the Azure classes makes it easier for us to handle blob interaction. The entire source code of example can be found in my Github

Leave a comment