Storage Shelve
Image courtesy of openclipart-vectors

Blob Storage Client Service

If you are working with Azure Blob Storage, you will frequently need to create a container, get hold of BlobContainerClient, upload a Blob, list blobs in a container, get a Blob Client, download a Blob, delete a container, set and read container metadata. Here are a couple of methods that help you handle these tasks.

Create Container
Get a BlobContainerClient
Upload a Blob
List Blobs
Get a BlobClient
Download a Blob
Delete a Container
Get Container Properties
Set Container Metadata

What's a Blob?

Any electronic file - word document, image, pdf file, json file etc. Those are examples of blobs. The word itself means binary large object

What's a Container?

It's like a folder where you can store blobs. Just like folders it helps with organization

First Steps

We'll create a service class to hold the various methods for interacting with containers and blobs. The class will need a connection string to your Azure storage account.

public class BlobsService
{
    private readonly string _connectionString;

    public BlobsService(string connectionString)
    {
        if (string.IsNullOrEmpty(connectionString))
        {
            throw new ArgumentException($"'{nameof(connectionString)}' cannot be null or empty.", nameof(connectionString));
        }
        _connectionString = connectionString;
    }
}

Create Container

The method below appends a guid to your preferred container name before creating and returning a blob container client.

public async Task CreateContainer(string name, CancellationToken cancellationToken)
{
    name = $"{name}{Guid.NewGuid()}";
    var response = await GetBlobServiceClient().CreateBlobContainerAsync(name, cancellationToken: cancellationToken);
    return response.Value;
}
    

Get Blob Container Client

In the snippet below, the method uses an instance of BlobServiceClient to fetch and return a blob container client for the specified container

public async Task GetBlobContainerClient(string containerName)
{
    return GetBlobServiceClient().GetBlobContainerClient(containerName);
}
    

Upload Blob

To upload a blob you need to provide the path to the file to be uploaded along with the destination container name

public async Task UploadBlob(string path, string containerName, CancellationToken cancellationToken, bool createIfNotExists = true)
{
    var containerClient = await GetBlobContainerClient(containerName);
    if (containerClient is null && createIfNotExists)
    {
        containerClient = await CreateContainer(containerName, cancellationToken: cancellationToken);
    }
    if (containerClient is null) throw new BlobServiceException($"Could not find or create container {containerName}");
    var blobClient = await GetBlobClient(path, containerName, cancellationToken: cancellationToken);
    using FileStream uploadFileStream = File.OpenRead(path);
    await blobClient.UploadAsync(uploadFileStream);
    uploadFileStream.Close();
}
    

List Blobs

The method below returns all the blob items in the specified container

public async Task> ListBlobs(string containerName, CancellationToken cancellationToken)
{
    if (containerName is null)
    {
        throw new ArgumentNullException(nameof(containerName));
    }

    var containerClient = await GetBlobContainerClient(containerName) ?? throw new BlobServiceException("Unable to find Container");
    var blobs = new List();
    await foreach (var blobItem in containerClient.GetBlobsAsync(cancellationToken: cancellationToken))
    {
        blobs.Add(blobItem);
    }
    return blobs;
}
    

Get a Blob Client

You will need a blob client to upload, download and delete a blob. To get one you must provide a container name

public async Task GetBlobClient(string name, string containerName, CancellationToken cancellationToken)
{
    var containerClient = await GetBlobContainerClient(containerName) ?? throw new BlobServiceException("Unable to find Container");
    return containerClient.GetBlobClient(name);
}
        

Download a Blob

To download a blob, we need to know the name of the blob, the name of it's container and the location to download it to.

public async Task DownloadBlob(string name, string containerName, string downloadFilePath, CancellationToken cancellationToken)
{
    var blobClient = await GetBlobClient(name, containerName, cancellationToken: cancellationToken);
    using Stream downloadStream = await blobClient.OpenReadAsync(cancellationToken: cancellationToken);
    using FileStream fileStream = File.OpenWrite(downloadFilePath);
    await downloadStream.CopyToAsync(fileStream, cancellationToken);
}
    

Delete a Container

To delete a container, we need to know the container name. The service uses the connection string provided at initialization to connect to your azure storage account and perform the deletion

public async Task DeleteContainer(string containerName, CancellationToken cancellationToken)
{
    var containerClient = await GetBlobContainerClient(containerName);
    await containerClient.DeleteAsync(cancellationToken: cancellationToken);
}
    

Get Container Properties

The method requires the container name and accepts an optional cancellationToken

public async Task GetContainerProperties(string containerName, CancellationToken cancellationToken)
{
    var containerClient = await GetBlobContainerClient(containerName);
    return await containerClient.GetPropertiesAsync(cancellationToken: cancellationToken);
}
    

Set Container Metadata

Metadata should be provided a collection of key value pairs, with unique keys, along with the container name and accepts an optional cancellationToken

public async Task SetMetaData(IDictionary metadata, string containerName, CancellationToken cancellationToken)
{
    var containerClient = await GetBlobContainerClient(containerName);
    await containerClient.SetMetadataAsync(metadata, cancellationToken: cancellationToken);
}
    

Read Container Metadata

The method accepts a container name and returns the metadata as a dictionary of keys and values

public async Task> ReadContainerMetadata(string containerName, CancellationToken cancellationToken)
{
    var properties = await GetContainerProperties(containerName, cancellationToken);
    return properties.Metadata;
}
        

Conclusion

Having a utility class with the methods above can simplify interacting with Azure Blob Storage. Here is the entire class for your convenience.

Published July 9, 2023