One of the several cloud providers that e.GO Mobile uses for its IT infrastructure and products is Microsoft Azure.

To securely and easily store data, especially files, many Azure Blob Storages are used.

Therefore, this article deals with the topic of how to save a complete container using C# in a few amount of code.

Create project

Open your terminal application and create a new folder, lets say blob-backup, change to it and execute

dotnet new console --use-program-main

to setup a basic hello world application.

One note: I always recommend using –use-program-main flag because it can be difficult for beginners to understand how the new implicit functions work in .NET and C#, as references such as imported namespaces are not immediately visible.

Check with

dotnet run

if anything works fine and you get the expected output.

My solution can be found on GitHub.

Required packages

The only nuget packages I have installed were

You can install the latest versions from the command line with dotnet CLI:

dotnet add package Azure.Storage.Blobs
dotnet add package DotEnv.Core

Environment variables

For the demo application, I defined the following environment variables, which store all connection information we require:

  • TGF_AZURE_BLOB_STORAGE_CONNECTION_STRING: The connection string from Azure Portal
  • TGF_AZURE_BLOB_STORAGE_CONTAINER: The name of the container to backup

This is imo more secure as to submit them via shell command.

The API

Fortunately, the API of Azure.Storage.Blobs is very similar to its Node.js counterpart.

The first thing we need is a blob container client:

// ...
using Azure.Storage.Blobs;

// ...

class Program
{
    // ...

    async static Task<int> Main(string[] args)
    {
        // ...

        var connectionString = Environment.GetEnvironmentVariable("TGF_AZURE_BLOB_STORAGE_CONNECTION_STRING")?.Trim();
        var containerName = Environment.GetEnvironmentVariable("TGF_AZURE_BLOB_STORAGE_CONTAINER")?.Trim();

        var container = new BlobContainerClient(connectionString!, containerName!);

        // ...
    }
}

With its GetBlobsAsync() method we can access a GetAsyncEnumerator() method that creates us an async enumerator, which we can use to iterate step by step throught all blob:

// ...

class Program
{
    // ...

    async static Task<int> Main(string[] args)
    {
        // ...

        var blobEnumerator = container.GetBlobsAsync().GetAsyncEnumerator();
        while (await blobEnumerator.MoveNextAsync())
        {
            var blob = blobEnumerator.Current;

            // ...
        }

        // ...
    }
}

Like in Node.js, we must create a new BlobClient instance from the BlobItem in blob, before we can use one of the several download methods of it:

// ...

class Program
{
    // ...

    async static Task<int> Main(string[] args)
    {
        // ...

        while (await blobEnumerator.MoveNextAsync())
        {
            var blob = blobEnumerator.Current;

            // using fullname of `blob` to create
            // the instance of the blob client ...
            var blobClient = container.GetBlobClient(blob!.Name);

            // ... we need to download the underlying blob to
            // a local file
            await blobClient.DownloadToAsync("/path/to/local/target/file");

            // ...
        }

        // ...
    }
}

Conclusion

Fortunately, Microsoft has kept the API of its Azure Storage Client libraries very consistent across languages and frameworks, making the learning curve very flat.

The modules and libraries, in whatever language, are very extensive and powerful.

Have fun while trying it out! 🎉