DeletingMultipleObjectsUsingNetSDK

Deleting Multiple Objects Using the AWS SDK for .NET

The AWS SDK for .NET provides a convenient method for deleting multiple objects: DeleteObjects. For each object that you want to delete, you specify the key name and the version of the object. If the bucket is not versioning-enabled, you specify null for the version ID. If an exception occurs, review the DeleteObjectsException response to determine which objects were not deleted and why.

Example Deleting Multiple Objects from a Non-Versioning Bucket
The following C# example uses the multi-object delete API to delete objects from a bucket that is not version-enabled. The example uploads the sample objects to the bucket, and then uses the DeleteObjects method to delete the objects in a single request. In the DeleteObjectsRequest, the example specifies only the object key names because the version IDs are null.
For information about creating and testing a working sample, see Running the Amazon S3 .NET Code Examples.

using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Amazon.DocSamples.S3
{
class DeleteMultipleObjectsNonVersionedBucketTest
{
private const string bucketName = "*** versioning-enabled bucket name ***";
// Specify your bucket region (an example region is shown).
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
private static IAmazonS3 s3Client;
public static void Main()
{
s3Client = new AmazonS3Client(bucketRegion);
MultiObjectDeleteAsync().Wait();
}
static async Task MultiObjectDeleteAsync()
{
// Create sample objects (for subsequent deletion).
var keysAndVersions = await PutObjectsAsync(3);
// a. multi-object delete by specifying the key names and version IDs.
DeleteObjectsRequest multiObjectDeleteRequest = new DeleteObjectsRequest
{
BucketName = bucketName,
Objects = keysAndVersions // This includes the object keys and null version IDs.
};
// You can add specific object key to the delete request using the .AddKey.
// multiObjectDeleteRequest.AddKey("TickerReference.csv", null);
try
{
DeleteObjectsResponse response = await s3Client.DeleteObjectsAsync(multiObjectDeleteRequest);
Console.WriteLine("Successfully deleted all the {0} items", response.DeletedObjects.Count);
}
catch (DeleteObjectsException e)
{
PrintDeletionErrorStatus(e);
}
}
private static void PrintDeletionErrorStatus(DeleteObjectsException e)
{
// var errorResponse = e.ErrorResponse;
DeleteObjectsResponse errorResponse = e.Response;
Console.WriteLine("x {0}", errorResponse.DeletedObjects.Count);
Console.WriteLine("No. of objects successfully deleted = {0}", errorResponse.DeletedObjects.Count);
Console.WriteLine("No. of objects failed to delete = {0}", errorResponse.DeleteErrors.Count);
Console.WriteLine("Printing error data...");
foreach (DeleteError deleteError in errorResponse.DeleteErrors)
{
Console.WriteLine("Object Key: {0}\t{1}\t{2}", deleteError.Key, deleteError.Code, deleteError.Message);
}
}
static async Task<List<KeyVersion>> PutObjectsAsync(int number)
{
List<KeyVersion> keys = new List<KeyVersion>();
for (int i = 0; i < number; i++)
{
string key = "ExampleObject-" + new System.Random().Next();
PutObjectRequest request = new PutObjectRequest
{
BucketName = bucketName,
Key = key,
ContentBody = "This is the content body!",
};
PutObjectResponse response = await s3Client.PutObjectAsync(request);
KeyVersion keyVersion = new KeyVersion
{
Key = key,
// For non-versioned bucket operations, we only need object key.
// VersionId = response.VersionId
};
keys.Add(keyVersion);
}
return keys;
}
}
}

Example Multi-Object Deletion for a Version-Enabled Bucket
The following C# example uses the multi-object delete API to delete objects from a version-enabled bucket. The example performs the following actions:

  1. Creates sample objects and deletes them by specifying the key name and version ID for each object. The operation deletes specific versions of the objects.

  2. Creates sample objects and deletes them by specifying only the key names. Because the example doesn't specify version IDs, the operation only adds delete markers. It doesn't delete any specific versions of the objects. After deletion, these objects don't appear in the Amazon S3 console.

  3. Deletes the delete markers by specifying the object keys and version IDs of the delete markers. When the operation deletes the delete markers, the objects reappear in the console. For information about creating and testing a working sample, see Running the Amazon S3 .NET Code Examples.

using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Amazon.DocSamples.S3
{
class DeleteMultipleObjVersionedBucketTest
{
private const string bucketName = "*** versioning-enabled bucket name ***";
// Specify your bucket region (an example region is shown).
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
private static IAmazonS3 s3Client;
public static void Main()
{
s3Client = new AmazonS3Client(bucketRegion);
DeleteMultipleObjectsFromVersionedBucketAsync().Wait();
}
private static async Task DeleteMultipleObjectsFromVersionedBucketAsync()
{
// Delete objects (specifying object version in the request).
await DeleteObjectVersionsAsync();
// Delete objects (without specifying object version in the request).
var deletedObjects = await DeleteObjectsAsync();
// Additional exercise - remove the delete markers S3 returned in the preceding response.
// This results in the objects reappearing in the bucket (you can
// verify the appearance/disappearance of objects in the console).
await RemoveDeleteMarkersAsync(deletedObjects);
}
private static async Task<List<DeletedObject>> DeleteObjectsAsync()
{
// Upload the sample objects.
var keysAndVersions2 = await PutObjectsAsync(3);
// Delete objects using only keys. Amazon S3 creates a delete marker and
// returns its version ID in the response.
List<DeletedObject> deletedObjects = await NonVersionedDeleteAsync(keysAndVersions2);
return deletedObjects;
}
private static async Task DeleteObjectVersionsAsync()
{
// Upload the sample objects.
var keysAndVersions1 = await PutObjectsAsync(3);
// Delete the specific object versions.
await VersionedDeleteAsync(keysAndVersions1);
}
private static void PrintDeletionReport(DeleteObjectsException e)
{
var errorResponse = e.Response;
Console.WriteLine("No. of objects successfully deleted = {0}", errorResponse.DeletedObjects.Count);
Console.WriteLine("No. of objects failed to delete = {0}", errorResponse.DeleteErrors.Count);
Console.WriteLine("Printing error data...");
foreach (var deleteError in errorResponse.DeleteErrors)
{
Console.WriteLine("Object Key: {0}\t{1}\t{2}", deleteError.Key, deleteError.Code, deleteError.Message);
}
}
static async Task VersionedDeleteAsync(List<KeyVersion> keys)
{
// a. Perform a multi-object delete by specifying the key names and version IDs.
var multiObjectDeleteRequest = new DeleteObjectsRequest
{
BucketName = bucketName,
Objects = keys // This includes the object keys and specific version IDs.
};
try
{
Console.WriteLine("Executing VersionedDelete...");
DeleteObjectsResponse response = await s3Client.DeleteObjectsAsync(multiObjectDeleteRequest);
Console.WriteLine("Successfully deleted all the {0} items", response.DeletedObjects.Count);
}
catch (DeleteObjectsException e)
{
PrintDeletionReport(e);
}
}
static async Task<List<DeletedObject>> NonVersionedDeleteAsync(List<KeyVersion> keys)
{
// Create a request that includes only the object key names.
DeleteObjectsRequest multiObjectDeleteRequest = new DeleteObjectsRequest();
multiObjectDeleteRequest.BucketName = bucketName;
foreach (var key in keys)
{
multiObjectDeleteRequest.AddKey(key.Key);
}
// Execute DeleteObjects - Amazon S3 add delete marker for each object
// deletion. The objects disappear from your bucket.
// You can verify that using the Amazon S3 console.
DeleteObjectsResponse response;
try
{
Console.WriteLine("Executing NonVersionedDelete...");
response = await s3Client.DeleteObjectsAsync(multiObjectDeleteRequest);
Console.WriteLine("Successfully deleted all the {0} items", response.DeletedObjects.Count);
}
catch (DeleteObjectsException e)
{
PrintDeletionReport(e);
throw; // Some deletes failed. Investigate before continuing.
}
// This response contains the DeletedObjects list which we use to delete the delete markers.
return response.DeletedObjects;
}
private static async Task RemoveDeleteMarkersAsync(List<DeletedObject> deletedObjects)
{
var keyVersionList = new List<KeyVersion>();
foreach (var deletedObject in deletedObjects)
{
KeyVersion keyVersion = new KeyVersion
{
Key = deletedObject.Key,
VersionId = deletedObject.DeleteMarkerVersionId
};
keyVersionList.Add(keyVersion);
}
// Create another request to delete the delete markers.
var multiObjectDeleteRequest = new DeleteObjectsRequest
{
BucketName = bucketName,
Objects = keyVersionList
};
// Now, delete the delete marker to bring your objects back to the bucket.
try
{
Console.WriteLine("Removing the delete markers .....");
var deleteObjectResponse = await s3Client.DeleteObjectsAsync(multiObjectDeleteRequest);
Console.WriteLine("Successfully deleted all the {0} delete markers",
deleteObjectResponse.DeletedObjects.Count);
}
catch (DeleteObjectsException e)
{
PrintDeletionReport(e);
}
}
static async Task<List<KeyVersion>> PutObjectsAsync(int number)
{
var keys = new List<KeyVersion>();
for (var i = 0; i < number; i++)
{
string key = "ObjectToDelete-" + new System.Random().Next();
PutObjectRequest request = new PutObjectRequest
{
BucketName = bucketName,
Key = key,
ContentBody = "This is the content body!",
};
var response = await s3Client.PutObjectAsync(request);
KeyVersion keyVersion = new KeyVersion
{
Key = key,
VersionId = response.VersionId
};
keys.Add(keyVersion);
}
return keys;
}
}
}