Get a reference of Azure blob by the full Uri not the blob name?
Asked Answered
L

4

10

I 'm saving the uri of the file in the database in this form:

https://app.blob.core.windows.net/container/Accounts/Images/acc.jpg

But to delete it I need to pass only the blob name, when I try this

CloudBlockBlob blockBlob = Container.GetBlockBlobReference(uri);

The blob's full uri becomes:

https://app.blob.core.windows.net/container/https://app.blob.core.windows.net/container/Accounts/Images/acc.jpg

So I get 404 error (not found), I can do some trimming to the uri but that doesn't seem efficient. so is there a way to delete a blob/ get reference by its full URI?

Longinus answered 16/2, 2017 at 14:42 Comment(0)
M
9

It is possible to do this creating the CloudBlockBlob with this constructor:

public CloudBlockBlob(Uri blobAbsoluteUri)

In your case, assuming uri is of type Uri and not just a string:

CloudBlockBlob blob = new CloudBlockBlob(uri);

You might need to use your credentials if the blob isn't public or the uri doesn't contain SAS credentials (like to one you included). In that case you will need this constructor:

public CloudBlockBlob(Uri blobAbsoluteUri, StorageCredentials credentials)

As stated by Zhaoxing Lu - Microsoft on the comments,

Public access is read only access, you need to specify the storage account key or Shared Access Signature for deleting operation.

Multiangular answered 16/2, 2017 at 14:49 Comment(12)
The Uri is correct now, but still getting the same 404 error?Longinus
Is the blob/container public?Multiangular
Yes, it's public. I tried to trim the Uri and used GetBlockBlobReference method, and, somehow, it worksLonginus
I tried it on my container and it worked, which method gives you the 404? I tried with blob.Exists() without any problem on v8Multiangular
blockBlob.DeleteIfExists();Longinus
In that case it fails, just like you said. I would report it on github seems it might be a bug (given that Exists returns true). Delete also throws the same exception.Multiangular
It's not a bug. Public access is read only access, you need to specify the storage account key or Shared Access Signature for deleting operation.Durmast
@ZhaoxingLu-Microsoft right, it makes sense. What's strange is that it returns 404 instead of 401Multiangular
We don't want to let unauthorized people know if the resource really exists, so Azure Storage FE returns 404 no matter whether the resource exists. You can see 403 (Forbidden) part in w3.org/Protocols/rfc2616/rfc2616-sec10.html : "If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead."Durmast
Github does the same thing when you try to access a private repository without credentials. It returns a 404.Hemihedral
Also to add a note - the credentials can be obtained from the CloudBlobClient.Credentials property.Oaken
how would you download the blob just by using the uri?Rozella
Y
18

I did face similar issue , since i already had valid container reference this worked for me :

CloudBlockBlob blockblob = container.GetBlockBlobReference(new CloudBlockBlob(blobUri).Name);
Yardley answered 9/11, 2017 at 23:46 Comment(2)
so what if we dont know the container without looking at the entire URI like https://xxxxxx.blob.core.windows.net/input/DisabledFlights[1].cache and in this case the container is input ive asked a question #57081049Rozella
I took more than 1 hour to find it :p. ThanksHartebeest
M
9

It is possible to do this creating the CloudBlockBlob with this constructor:

public CloudBlockBlob(Uri blobAbsoluteUri)

In your case, assuming uri is of type Uri and not just a string:

CloudBlockBlob blob = new CloudBlockBlob(uri);

You might need to use your credentials if the blob isn't public or the uri doesn't contain SAS credentials (like to one you included). In that case you will need this constructor:

public CloudBlockBlob(Uri blobAbsoluteUri, StorageCredentials credentials)

As stated by Zhaoxing Lu - Microsoft on the comments,

Public access is read only access, you need to specify the storage account key or Shared Access Signature for deleting operation.

Multiangular answered 16/2, 2017 at 14:49 Comment(12)
The Uri is correct now, but still getting the same 404 error?Longinus
Is the blob/container public?Multiangular
Yes, it's public. I tried to trim the Uri and used GetBlockBlobReference method, and, somehow, it worksLonginus
I tried it on my container and it worked, which method gives you the 404? I tried with blob.Exists() without any problem on v8Multiangular
blockBlob.DeleteIfExists();Longinus
In that case it fails, just like you said. I would report it on github seems it might be a bug (given that Exists returns true). Delete also throws the same exception.Multiangular
It's not a bug. Public access is read only access, you need to specify the storage account key or Shared Access Signature for deleting operation.Durmast
@ZhaoxingLu-Microsoft right, it makes sense. What's strange is that it returns 404 instead of 401Multiangular
We don't want to let unauthorized people know if the resource really exists, so Azure Storage FE returns 404 no matter whether the resource exists. You can see 403 (Forbidden) part in w3.org/Protocols/rfc2616/rfc2616-sec10.html : "If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead."Durmast
Github does the same thing when you try to access a private repository without credentials. It returns a 404.Hemihedral
Also to add a note - the credentials can be obtained from the CloudBlobClient.Credentials property.Oaken
how would you download the blob just by using the uri?Rozella
L
7

You can now use the BlobUriBuilder class to safely get the blob name from the URI without the need for string parsing or other methods.

BlobUriBuilder blobUriBuilder = new BlobUriBuilder(new Uri(blobUri));
var sourceBlob = container.GetBlobClient(blobUriBuilder.BlobName);
Lederer answered 17/2, 2022 at 9:44 Comment(0)
F
-2

Your problem is that you're putting the URI string inside the blob name with this function GetBlockBlobReference as defined: public virtual CloudBlockBlob GetBlockBlobReference(string blobName);. You will use moondaisy solution's.

Frill answered 24/6, 2018 at 15:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.