Create and list blob versions in .NET

Blob versioning automatically creates a previous version of a blob anytime it is modified or deleted. When blob versioning is enabled, then you can restore an earlier version of a blob to recover your data if it is erroneously modified or deleted.

For optimal data protection, Microsoft recommends enabling both blob versioning and blob soft delete for your storage account. For more information, see Blob versioning and Soft delete for blobs.

Modify a blob to trigger a new version

The following code example shows how to trigger the creation of a new version with the Azure Storage client library for .NET, version 12.5.1 or later. Before running this example, make sure you have enabled versioning for your storage account.

The example creates a block blob, and then updates the blob's metadata. Updating the blob's metadata triggers the creation of a new version. The example retrieves the initial version and the current version, and shows that only the current version includes the metadata.

public static async Task UpdateVersionedBlobMetadata(BlobContainerClient blobContainerClient, 
                                                     string blobName)
{
    try
    {
        // Create the container.
        await blobContainerClient.CreateIfNotExistsAsync();

        // Upload a block blob.
        BlockBlobClient blockBlobClient = blobContainerClient.GetBlockBlobClient(blobName);

        string blobContents = string.Format("Block blob created at {0}.", DateTime.Now);
        byte[] byteArray = Encoding.ASCII.GetBytes(blobContents);

        string initalVersionId;
        using (MemoryStream stream = new MemoryStream(byteArray))
        {
            Response<BlobContentInfo> uploadResponse = 
                await blockBlobClient.UploadAsync(stream, null, default);

            // Get the version ID for the current version.
            initalVersionId = uploadResponse.Value.VersionId;
        }

        // Update the blob's metadata to trigger the creation of a new version.
        Dictionary<string, string> metadata = new Dictionary<string, string>
        {
            { "key", "value" },
            { "key1", "value1" }
        };

        Response<BlobInfo> metadataResponse = 
            await blockBlobClient.SetMetadataAsync(metadata);

        // Get the version ID for the new current version.
        string newVersionId = metadataResponse.Value.VersionId;

        // Request metadata on the previous version.
        BlockBlobClient initalVersionBlob = blockBlobClient.WithVersion(initalVersionId);
        Response<BlobProperties> propertiesResponse = await initalVersionBlob.GetPropertiesAsync();
        PrintMetadata(propertiesResponse);

        // Request metadata on the current version.
        BlockBlobClient newVersionBlob = blockBlobClient.WithVersion(newVersionId);
        Response<BlobProperties> newPropertiesResponse = await newVersionBlob.GetPropertiesAsync();
        PrintMetadata(newPropertiesResponse);
    }
    catch (RequestFailedException e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    }
}

static void PrintMetadata(Response<BlobProperties> propertiesResponse)
{
    if (propertiesResponse.Value.Metadata.Count > 0)
    {
        Console.WriteLine("Metadata values for version {0}:", propertiesResponse.Value.VersionId);
        foreach (var item in propertiesResponse.Value.Metadata)
        {
            Console.WriteLine("Key:{0}  Value:{1}", item.Key, item.Value);
        }
    }
    else
    {
        Console.WriteLine("Version {0} has no metadata.", propertiesResponse.Value.VersionId);
    }
}

List blob versions

To list blob versions, specify the BlobStates parameter with the Version field. Versions are listed from oldest to newest.

The following code example shows how to list blob versions.

private static void ListBlobVersions(BlobContainerClient blobContainerClient, 
                                           string blobName)
{
    try
    {
        // Call the listing operation, specifying that blob versions are returned.
        // Use the blob name as the prefix. 
        var blobVersions = blobContainerClient.GetBlobs
            (BlobTraits.None, BlobStates.Version, prefix: blobName)
            .OrderByDescending(version => version.VersionId).Where(blob => blob.Name == blobName);

        // Construct the URI for each blob version.
        foreach (var version in blobVersions)
        {
            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobContainerClient.Uri)
            {
                BlobName = version.Name,
                VersionId = version.VersionId
            };

            if ((bool)version.IsLatestVersion.GetValueOrDefault())
            {
                Console.WriteLine("Current version: {0}", blobUriBuilder);
            }
            else
            {
                Console.WriteLine("Previous version: {0}", blobUriBuilder);
            }
        }
    }
    catch (RequestFailedException e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    }
}

Copy a previous blob version over the base blob

You can perform a copy operation to promote a version over its base blob, as long as the base blob is in an online tier (hot or cool). The version remains, but its destination is overwritten with a copy that can be read and written to.

The following code example shows how to copy a blob version over the base blob:

public static async Task<BlockBlobClient> CopyVersionOverBaseBlobAsync(
    BlockBlobClient client,
    string versionTimestamp)
{
    // Instantiate BlobClient with identical URI and add version timestamp
    BlockBlobClient versionClient = client.WithVersion(versionTimestamp);

    // Restore the specified version by copying it over the base blob
    await client.SyncUploadFromUriAsync(versionClient.Uri);

    // Return the client object after the copy operation
    return client;
}

Resources

To learn more about managing blob versions using the Azure Blob Storage client library for .NET, see the following resources.

Client library resources

See also