ContentHash is null in Azure.Storage.Blobs v12.x.x
Asked Answered
S

2

8

I am trying to upgrade my project from Microsoft.WindowsAzure.Storage v9 (deprecated) to latest sdk Azure.Storage.Blobs v12.

My issue (post-upgrade) is accessing the ContentHash property.

Pre-upgrade steps:

  1. upload file to blob
  2. get MD5 hash of uploaded file provided by CloudBlob.Properties.ContentMD5 from Microsoft.WindowsAzure.Storage.Blob
  3. compare the calculated MD5 hash with the one retrieved from azure

Post-upgrade attempts to access the MD5 hash that Azure is calculating on its side:

1.BlobClient.GetProperties() calling this method

2.BlobClient.UploadAsync() looking at the BlobContentInfo response

both return ContentHash is null. (see my later Question to see why)

One huge difference I've noticed is that with older sdk I could tell to the storage client to use MD5 computing like this:

CloudBlobClient cloudBlobClient = _cloudStorageAccount.CreateCloudBlobClient();

cloudBlobClient.DefaultRequestOptions.StoreBlobContentMD5 = true;

So I was expecting to find something similar to StoreBlobContentMD5 on the latest sdk but I couldn't.

Can anyone help me find a solution for this problem?

Edit 1: I did a test and in azure storage I do not have a MD5 hash

Upload code:

var container = _blobServiceClient.GetBlobContainerClient(containerName);
var blob = container.GetBlobClient(blobPath);

BlobHttpHeaders blobHttpHeaders = null;
if (!string.IsNullOrWhiteSpace(fileContentType))
{
    blobHttpHeaders = new BlobHttpHeaders()
   {
        ContentType = fileContentType,                   
   };                
}

StorageTransferOptions storageTransferOption = new StorageTransferOptions()
     {
          MaximumConcurrency = 2,
     };

var blobResponse = await blob.UploadAsync(stream, blobHttpHeaders, null, null, null, null, storageTransferOption, default);

return blob.GetProperties();

There is not much difference between old upload code and new one apart from using new classes from new sdk.

The main difference remains the one I already stated, I can not find an equivalent setting in new sdk for StoreBlobContentMD5 . I think this is the problem. I need to set the storage client to compute MD5 hash, as I did with old sdk.

Edit 2: For download I can do something like this:

var properties = blob.GetProperties();
var download = await blob.DownloadAsync(range: new HttpRange(0, properties.Value.ContentLength), rangeGetContentHash: true);

By using this definition of DownloadAsync I can force MD5 hash to be calculated and it can be found in download.Value.ContentHash

Selfinduced answered 20/7, 2020 at 13:23 Comment(9)
Can you confirm in the Azure Portal if the blob has a ContentHash? So that we know if the issue is with the upload or with the retrieval of attributes? Maybe you could post an example of your Upload and Download code too once we know where the issue is?Cecelia
I just did a test and in azure storage I do not have a MD5 hash.Selfinduced
Added a pic and a code snippet. blobResponse.ContentHash and blob.GetProperties().ContentHash are both null.Selfinduced
@Selfinduced As fra as I knew, if blob service api version is 2012-02-12 and later, the server will return MD hash in response header even when the request header does not include the Content-MD5: learn.microsoft.com/en-us/rest/api/storageservices/…Unreason
Yes, I read that too and based on that doc I was expecting to work....Surely I do something wrong, but I can't find what.Selfinduced
Even using the Microsoft Storage Explorer if you use the wrong upload method you don't get your MD5 generated for you, so maybe try using the different upload methods you see in there to experiment? Can you try using the BlockBlobClient instead?Cecelia
Already did, still not working.Selfinduced
@Cristian, could you please let me know the exact version of the package you're using, and the value of the fileContentType? I did a quick test with the v12.4.4 package, and the content md5 is auto-generated and can be read.Makassar
@IvanYang upon futher investigation it seems to be a problem with my solution. I did also a test on a clean up project and everything it seems to work as expected. I am using v12.4.4.0 of Azure.Storage.Blobs. Currently I am thinking that there is a conflict somewhere between libraries and somehow I end up without hashSelfinduced
M
1

Summarize to close the question:

I did a quick test with the latest version of 12.4.4 blob storage package, I can see the content-md5 is auto-generated and can also be read.

And as per the op's comment, it may due to some issues with the existing solution. And after creating a new solution, it works as expected.

Makassar answered 29/7, 2020 at 9:29 Comment(2)
Sorry, this is not longer the solution of this problem. After some more time spend debugging I've found the route cause of it. Here yo can find the new post: #63352499Selfinduced
@Cristian, I see the new case, could you please provide a sample working code?Makassar
S
1

The short version of this problem is, make sure the Stream you upload to Azure using the v12 version of the SDK supports Seek (see the HasSeek property). It's currently required in order to traverse the Stream to generate the hash, and reset/seek the position back to 0 so that it can be read again for the actual upload.

Stationery answered 9/9, 2020 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.