Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContentHash is null in Azure.Storage.Blobs v12.x.x

Tags:

c#

azure

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

like image 406
Cristian Avatar asked Jul 20 '20 13:07

Cristian


2 Answers

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.

like image 151
Ivan Yang Avatar answered Oct 13 '22 07:10

Ivan Yang


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.

like image 36
Nick Albrecht Avatar answered Oct 13 '22 08:10

Nick Albrecht