Azure Storage Blobs Batch client library for .NET - version 12.16.1

Server Version: 2021-02-12, 2020-12-06, 2020-10-02, 2020-08-04, 2020-06-12, 2020-04-08, 2020-02-10, 2019-12-12, 2019-07-07, and 2019-02-02

Azure Blob storage is Microsoft's object storage solution for the cloud. Blob storage is optimized for storing massive amounts of unstructured data. This library allows you to batch multiple Azure Blob Storage operations in a single request.

Source code | Package (NuGet) | API reference documentation | REST API documentation | Product documentation

Getting started

Install the package

Install the Azure Storage Blobs Batch client library for .NET with NuGet:

dotnet add package Azure.Storage.Blobs.Batch

Prerequisites

You need an Azure subscription and a Storage Account to use this package.

To create a new Storage Account, you can use the Azure Portal, Azure PowerShell, or the Azure CLI. Here's an example using the Azure CLI:

az storage account create --name MyStorageAccount --resource-group MyResourceGroup --location westus --sku Standard_LRS

Authenticate the client

In order to interact with the Azure Blobs Storage service for batch operations, you'll need to create an instance of the BlobServiceClient class. The Azure Identity library makes it easy to add Azure Active Directory support for authenticating Azure SDK clients with their corresponding Azure services.

// Create a BlobServiceClient that will authenticate through Active Directory
Uri accountUri = new Uri("https://MYSTORAGEACCOUNT.blob.core.windows.net/");
BlobServiceClient client = new BlobServiceClient(accountUri, new DefaultAzureCredential());
BlobBatchClient batch = client.GetBlobBatchClient();

Key concepts

Batching supports two types of subrequests: SetBlobAccessTier for block blobs and DeleteBlob for blobs.

  • Only supports up to 256 subrequests in a single batch. The size of the body for a batch request cannot exceed 4MB.
  • There are no guarantees on the order of execution of the batch subrequests.
  • Batch subrequest execution is not atomic. Each subrequest is executed independently.
  • Each subrequest must be for a resource within the same storage account.

Thread safety

We guarantee that all client instance methods are thread-safe and independent of each other (guideline). This ensures that the recommendation of reusing client instances is always safe, even across threads.

Additional concepts

Client options | Accessing the response | Long-running operations | Handling failures | Diagnostics | Mocking | Client lifetime

Examples

Deleting blobs

// Get a connection string to our Azure Storage account.
string connectionString = "<connection_string>";
string containerName = "sample-container";

// Get a reference to a container named "sample-container" and then create it
BlobServiceClient service = new BlobServiceClient(connectionString);
BlobContainerClient container = service.GetBlobContainerClient(containerName);
container.Create();

// Create three blobs named "foo", "bar", and "baz"
BlobClient foo = container.GetBlobClient("foo");
BlobClient bar = container.GetBlobClient("bar");
BlobClient baz = container.GetBlobClient("baz");
foo.Upload(BinaryData.FromString("Foo!"));
bar.Upload(BinaryData.FromString("Bar!"));
baz.Upload(BinaryData.FromString("Baz!"));

// Delete all three blobs at once
BlobBatchClient batch = service.GetBlobBatchClient();
batch.DeleteBlobs(new Uri[] { foo.Uri, bar.Uri, baz.Uri });

Setting Access Tiers

// Get a connection string to our Azure Storage account.
string connectionString = "<connection_string>";
string containerName = "sample-container";

// Get a reference to a container named "sample-container" and then create it
BlobServiceClient service = new BlobServiceClient(connectionString);
BlobContainerClient container = service.GetBlobContainerClient(containerName);
container.Create();
// Create three blobs named "foo", "bar", and "baz"
BlobClient foo = container.GetBlobClient("foo");
BlobClient bar = container.GetBlobClient("bar");
BlobClient baz = container.GetBlobClient("baz");
foo.Upload(BinaryData.FromString("Foo!"));
bar.Upload(BinaryData.FromString("Bar!"));
baz.Upload(BinaryData.FromString("Baz!"));

// Set the access tier for all three blobs at once
BlobBatchClient batch = service.GetBlobBatchClient();
batch.SetBlobsAccessTier(new Uri[] { foo.Uri, bar.Uri, baz.Uri }, AccessTier.Cool);

Fine-grained control

// Get a connection string to our Azure Storage account.
string connectionString = "<connection_string>";
string containerName = "sample-container";

// Get a reference to a container named "sample-container" and then create it
BlobServiceClient service = new BlobServiceClient(connectionString);
BlobContainerClient container = service.GetBlobContainerClient(containerName);
container.Create();

// Create three blobs named "foo", "bar", and "baz"
BlobClient foo = container.GetBlobClient("foo");
BlobClient bar = container.GetBlobClient("bar");
BlobClient baz = container.GetBlobClient("baz");
foo.Upload(BinaryData.FromString("Foo!"));
foo.CreateSnapshot();
bar.Upload(BinaryData.FromString("Bar!"));
bar.CreateSnapshot();
baz.Upload(BinaryData.FromString("Baz!"));

// Create a batch with three deletes
BlobBatchClient batchClient = service.GetBlobBatchClient();
BlobBatch batch = batchClient.CreateBatch();
batch.DeleteBlob(foo.Uri, DeleteSnapshotsOption.IncludeSnapshots);
batch.DeleteBlob(bar.Uri, DeleteSnapshotsOption.OnlySnapshots);
batch.DeleteBlob(baz.Uri);

// Submit the batch
batchClient.SubmitBatch(batch);

Troubleshooting

All Blob service operations will throw a RequestFailedException on failure with helpful ErrorCodes. Many of these errors are recoverable. Subrequest failures will be bundled together into an AggregateException.

// Get a connection string to our Azure Storage account.
string connectionString = "<connection_string>";
string containerName = "sample-container";

// Get a reference to a container named "sample-container" and then create it
BlobServiceClient service = new BlobServiceClient(connectionString);
BlobContainerClient container = service.GetBlobContainerClient(containerName);
container.Create();

// Create a blob named "valid"
BlobClient valid = container.GetBlobClient("valid");
valid.Upload(BinaryData.FromString("Valid!"));

// Get a reference to a blob named "invalid", but never create it
BlobClient invalid = container.GetBlobClient("invalid");

// Delete both blobs at the same time
BlobBatchClient batch = service.GetBlobBatchClient();
try
{
    batch.DeleteBlobs(new Uri[] { valid.Uri, invalid.Uri });
}
catch (AggregateException)
{
    // An aggregate exception is thrown for all the individual failures
    // Check ex.InnerExceptions for RequestFailedException instances
}

Next steps

Check out our sync and async samples for more.

Contributing

See the Storage CONTRIBUTING.md for details on building, testing, and contributing to this library.

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit cla.microsoft.com.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Impressions