Azure Storage Calculated MD5 does not match existing property
Asked Answered
M

3

13

I'm trying to pass an Azure Storage blob through an ashx. On the blockBlob.DownloadToStream(memoryStream) it's throwing the following Exception: Microsoft.WindowsAzure.Storage.StorageException: Calculated MD5 does not match existing property

I know it's finding the correct blob. If I put in a container and path that don't exist then it gives me a 404 exception instead.

I've Googled for hints on what might be causing this error but nothing useful is coming up. Does anyone have any thoughts on what might be causing this? I've rewritten this code a couple different ways over the last couple days but it always dies on DownloadToStream.

using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

public void ProcessRequest(HttpContext context) {
    // Retrieve storage account from connection string.
    Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(Microsoft.WindowsAzure.CloudConfigurationManager.GetSetting("StorageConnectionString"));

    // Create the blob client.
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    // Retrieve reference to a previously created container.
    CloudBlobContainer container = blobClient.GetContainerReference("gmt");

    // Retrieve reference to blob named "articles/142/222.jpg".
    CloudBlockBlob blockBlob = container.GetBlockBlobReference("articles/142/222.jpg");

    using (var memoryStream = new MemoryStream()) {
        blockBlob.DownloadToStream(memoryStream);
        byte[] photoByte = ReadFully(memoryStream);
        context.Response.Clear();
        context.Response.ContentType = "image/jpeg";
        context.Response.OutputStream.Write(photoByte, 0, photoByte.Length);
    }
}

public static byte[] ReadFully(Stream input) {
    input.Position = 0;
    using (MemoryStream ms = new MemoryStream()) {
        input.CopyTo(ms);
        return ms.ToArray();
    }
}
Magdau answered 12/12, 2013 at 14:36 Comment(0)
L
10

I was able to recreate the problem you're facing. This happens if the Content MD5 property of the blob is somehow corrupted. I had a blob with some content MD5 (which was correct). I then programmatically changed the MD5 to some other value (which is incorrect). Now when I call DownloadToStream() method on the blob, I get exact same error.

You can bypass this check by setting DisableContentMD5Validation to true in BlobRequestOptions as shown in the code below:

            BlobRequestOptions options = new BlobRequestOptions()
            {
                DisableContentMD5Validation = true,
            };
            blockBlob.DownloadToStream(memoryStream, null, options);

Give it a try and it should work.

On a side note, you may want to modify your ReadFully method as well. You would need to move the input stream pointer to the beginning.

    public static byte[] ReadFully(Stream input)
    {
        input.Position = 0;//Positioning it to the top of stream.
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
Levenson answered 12/12, 2013 at 15:36 Comment(4)
Thanks. I'll try this out tonight. I uploaded 13 gigs of images using the FTP to Azure Blob Storage Bridge. Every file I tried gives me this error message. I wonder if this is what corrupted all of the files.Magdau
that made the exception go away thanks. the ashx is still just returning 0 bytes though. booooooo...Magdau
Just check the position of ms in ReadFully() function of yours. Make sure it is also at 0.Levenson
ah, i found it. there's another mistake in my code. I need to ReadFully(memoryStream) and not stream. That's just some empty MemoryStream object. It works now! Thank you so much for your help and quick responses. ;)Magdau
P
3

I had this problem on my local DEV environment. And it seems that db of AzureStorageEmulator got corrupted.

The solution (for local env!):

  • drop the emulator's db (e.g. AzureStorageEmulatorDb57)
  • run AzureStorageEmulator.exe init -sqlinstance . (you may need to customize the instance name)
  • run AzureStorageEmulator.exe start
  • restart the application, so it gets a new handler to the emulator
Publia answered 2/10, 2019 at 13:51 Comment(3)
from where to drop emulators db. Not getting the steps. Please explain in more detailLauritz
@Lauritz - the emulator create a database on your local SQL Server instance. During first initialisation you had to specify the SQL instance, so the emulator can store its data these. In the steps above the dot "." means "default local sql server instance".Publia
Stopping everything and dropping the emulator DB and then relaunching the application is all I needed to do. It auto starts the emulator and automatically recreated the emulatorDb and VOILA, no more errors! Thank you!Overdone
E
2

I had the same issue. I used AzureStorageEmulator.exe init -forcecreate. Described in this link. MD5 error message is now gone.

Eun answered 24/10, 2020 at 2:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.