Home > Mobile >  ListBlobs does not list Deleted blobs
ListBlobs does not list Deleted blobs

Time:12-14

I am trying to list all deleted blobs from an Azure Storage Account. Here is my code:

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

var blobClient = new CloudStorageAccount(new StorageCredentials("accountname", "accountkey"), true).CreateCloudBlobClient();
var container = blobClient.GetContainerReference("container");
var blobs = container.ListBlobs(useFlatBlobListing: true, blobListingDetails: BlobListingDetails.Deleted).ToList();

However, the result of ListBlobs is all non-deleted blobs in the container. In the Azure Portal I can clearly see there are many more deleted blobs in this container, but they are not being retrieved correctly.

How can I list only the blobs in deleted state in my container?

Edit:

I created a new container, with two blobs: test_deleted (which I deleted in the Azure Portal) and test_not_deleted. Using the newer Azure.Blob.Storage package, I now have the following code:

var client = new BlobServiceClient(new Uri($"https://{StorageAccountName}.blob.core.windows.net"), new StorageSharedKeyCredential(StorageAccountName, StorageAccountKey));
var container = client.GetBlobContainerClient("test");
var resultSegment = container.GetBlobsAsync(states: BlobStates.Deleted, traits: BlobTraits.All).AsPages(default, 5000);

var results = new List<BlobItem>();

await foreach (Azure.Page<BlobItem> blobPage in resultSegment)
{
    foreach (BlobItem blobItem in blobPage.Values)
    {
        results.Add(blobItem);
    }
}

The result contains only the not deleted blob.

Azure Portal screenshot

Results view

CodePudding user response:

After a lot of headache and some help from this answer, I have figured out how to retrieve the deleted blobs. For some reason, if both versioning and soft-delete are enabled, the blobs you retrieve do not have the Deleted property set to true. Instead, their VersionId property will be null.

It seems that when BlobStates.DeletedWithVersions is used, all blobs are retrieved, but for deleted blobs, VersionId will be null. Here is the seemingly working code which retrieves all the blobs marked deleted:

var client = new BlobServiceClient(new Uri($"https://{StorageAccountName}.blob.core.windows.net"), new StorageSharedKeyCredential(StorageAccountName, StorageAccountKey));
var container = client.GetBlobContainerClient("test");
var resultSegment = container.GetBlobsAsync(states: BlobStates.DeletedWithVersions, traits:BlobTraits.All).AsPages(default, 5000);

var deletedBlobs = new List<BlobItem>();

await foreach (Azure.Page<BlobItem> blobPage in resultSegment)
{
    foreach (BlobItem blobItem in blobPage.Values)
    {
        if (blobItem.VersionId == null)
        {
            deletedBlobs.Add(blobItem);
        }
    }
}

In my case, I needed to know if a blob was deleted on a certain day. When a blob is deleted, a new version is created. So to find the deletion day, you need to retrieve everything with the blob's name, using BlobStates.Version, and check the VersionId property of the blobs, which is a date string. This will contain the date the version was created (i.e. the blob was deleted).

foreach (var deletedBlob in deletedBlobs)
{
    var versions = container.GetBlobs(BlobTraits.None, BlobStates.Version, prefix: deletedBlob.Name);

    foreach(var v in versions)
    { 
        if (deletedOn == DateTime.Parse(v.VersionId))
        {
            Console.WriteLine($"Blob {deletedBlob.Name} deleted on {deletedOn}");
        }
    }
}

CodePudding user response:

You are using a very old NuGet package, you should upgrade to Azure.Storage.Blobs.

Then use paging to get all the blobs as shown on the docs:

private static async Task ListBlobsFlatListing(BlobContainerClient blobContainerClient, 
                                               int? segmentSize)
{
    try
    {
        // Call the listing operation and return pages of the specified size.
        var resultSegment = blobContainerClient.GetBlobsAsync()
            .AsPages(default, segmentSize);

        // Enumerate the blobs returned for each page.
        await foreach (Azure.Page<BlobItem> blobPage in resultSegment)
        {
            foreach (BlobItem blobItem in blobPage.Values)
            {
                Console.WriteLine("Blob name: {0}", blobItem.Name);
            }

            Console.WriteLine();
        }
    }
    catch (RequestFailedException e)
    {
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    }
}

Use the optional blobstates parameter to specify you want to list deleted blobs

  • Related