Home > Software design >  How to List Blobs in a Container iwth C# API using a SAS token
How to List Blobs in a Container iwth C# API using a SAS token

Time:05-09

I am using a SAS token to access Azure Blob Store using the c# API. I can successfully create new blobs in a container and, given the name of a blob, I can read that blob and get the contents. However, I am unable to LIST the blobs in the container as I get an InvalidURl error: The requested URI does not represent any resource on the server.

I am using the same sas URI for all three requests, upload, download, and list.

I generate the sas URI using the following code:

if (containerClient.CanGenerateSasUri)
{
     BlobSasBuilder sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = containerClient.Name,
        Resource = "c"
    };

    if (storedPolicyName == null)
    {
        sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddHours(1);
        sasBuilder.SetPermissions(BlobContainerSasPermissions.All);
    }
    else
    {
        sasBuilder.Identifier = storedPolicyName;
    }

    Uri sasUri = containerClient.GenerateSasUri(sasBuilder);
}

And I attempt to list the names of the blobs using the folowing code:

    var serviceClient = new BlobServiceClient(sasUri);
    var containerClient = serviceClient.GetBlobContainerClient(container);
    var blobs = containerClient.GetBlobsByHierarchyAsync();

    await foreach (var blob in blobs)
    {
        if (blob.IsBlob)
        {
            blobNames.Add(blob.Blob.Name);
        }           
    }

If I create the BlobServiceClient using the connection string (rather than a sas URI), then this code works and can list the blobs that I have uploaded using the sas URI, but using the sas URI fails with InvalidURL (even though is the same sas token that I just used to create the blob in the container and it has permissions to list blobs in the container).

If I hard code a known filename I can use the sas containerClient to create a working BlobClient:

    var blobClient = containerClient.GetBlobClient("blobname");
    if (await blobClient.ExistsAsync())
    {
        var stream = await blobClient.DownloadStreamingAsync();
        return stream.Value.Content;
    }

What do I need to do to get the List operation to work with the sas token? Any pointers to what I'm missing greatly appreciated!

CodePudding user response:

The reason you are running into issues is because you are using a Blob Container SAS URI to create BlobServiceClient and when you create a BlobContainerClient instance using the service client, the container name is repeated twice.

Possible solutions:

  1. Directly create an instance of BlobContainerClient using the container SAS URL. You can do something like:
containerClient = new BlobContainerClient(sasUri);
  1. Create an instance of BlobServiceClient using just the SAS token (and not SAS URL) and account endpoint. You can do something like:
var endpoint = $"{uri.Scheme}://{uri.Host}";
var sasToken = uri.Query;
var credentials = new AzureSasCredential(sasToken);
var serviceClient = new BlobServiceClient(new Uri(endpoint), credentials);
var containerClient = serviceClient.GetBlobContainerClient(container);
...
...rest of your code
...
  • Related