azureazure-blob-storageazure-sdk-.net

Can not read blobs through BlobContainerClient for blobs with empty folder prefixes


I first get all my blobs like this:

var resultSegment = await blobContainer.GetBlobsAsync().AsPages(continuationToken, batchSize).FirstOrDefaultAsync();

I iterate them like this:

foreach (var blobItem in resultSegment.Values)

When I try to read a blob with the name //somename (as in [empty folder]/[empty folder]/somename):

var blobClient = blobContainer.GetBlobClient(blobItem.Name);
var exists = await blobClient.ExistsAsync();
var tags = await blobClient.GetTagsAsync();

I get exists == false and an RequestFailedException on GetTagsAsync.

This works fine for the blobs that does not have empty folder prefixes.

I think this is very strange since blobContainer.GetBlobClient only takes one argument, the blob name, and I get the blob name directly from the BlobItem I've got from the GetBlobsAsync.

All my nuget packages are updated to latest versions.

Update

I was about to use Azure Storage Explorer to create some test data to investigate this further and it's interesting that I through that tool can not create a virtual folder without a name "Name must not be empty." and I can not specify consecutive slashes within the destination directory for a file: "Directory path must not contain consecutive slashes.".

So it seem that Azure do think that this is disallowed although I already have thousands and thousands of blobs with empty virtual path directory names.


Solution

  • What is happening here is that SDK is automatically removing the starting / characters from the blob name when you create a blob client currently and because of that your requests are failing.

    To fix this issue, please create an instance of BlobClient using the blob URI. For example, if you are using account name and key, here's how you can do it:

    foreach (var blobItem in resultSegment.Values)
    {
        var blobUri = new Uri($"{blobContainer.Uri}/{blobItem.Name}");//assuming blobContainer is an instance of BlobContainerClient
        var blobClient = new BlobClient(blobUri, new StorageSharedKeyCredential("account-name", "account-key"));
        var exists = await blobClient.ExistsAsync();//should come as true
        var tags = await blobClient.GetTagsAsync();//should not fail
    }
    

    Please see this link for all constructor overrides: https://learn.microsoft.com/en-us/dotnet/api/azure.storage.blobs.blobclient?view=azure-dotnet#constructors.