简体   繁体   中英

Azure Blob download(GET) causes failed PUT request

I'm downloading files from the Azure blob to display them to my users. The files are just resumes in doc/docx/pdf format. This used to work until few days ago, and only thing I did was update Azure SDK, so it might be the reason. Method is called from client-side, which ends up calling a method like this:

CloudBlobContainer container = GetContainer(containerName);
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
blockBlob.Properties.ContentType = contentType;

using (var fileStream = new MemoryStream())
{
    await blockBlob.DownloadToStreamAsync(fileStream);
    return fileStream;
}

GetContainer method is defined as follows:

try
{
    var storageAccount = StorageAccount;
    var blobClient = storageAccount.CreateCloudBlobClient();
    var container = blobClient.GetContainerReference(containerName);

    if (container.CreateIfNotExists())
    {
        container.SetPermissions(new BlobContainerPermissions
        {
             PublicAccess = BlobContainerPublicAccessType.Blob
        });
    }
    return container;
}
catch (Exception e)
{
    Logger.Error("GetBlobContainer fail", e);
}

As of yesterday, I keep seeing in Azure Application Insights failed dependency calls. Not errors, just failed dependencies. Every time the file is downloaded, GET request is executed, but at the same time PUT request is also executed for some reason, and it fails. In the image below, you can see the Insights log for this error. Each one looks the same. The method is called, file downloaded and then that PUT request being called...

在此输入图像描述

Why is this PUT request being created, and how to solve this behavior, it's driving me crazy. What's also interesting is that everything works fine, as far as I can see, and this is happening with all my upload and download calls to blobs.

As mentioned in the release notes about Microsoft Azure Storage Libraries for .NET for version 8.0.0:

CreateIfNotExists methods will now only do one REST call instead of two.

Here is my test, you could refer to it for a better understanding of this change:

Prior to version 8.0.0, CreateIfNotExists would check the existence of the target, then create the resource if not exists as follows:

While after this version 8.0.0, CreateIfNotExists would invoke the create method directly and wrap this operation with try-catch to capture the exception.

In summary, this issue dues to the changes of the Microsoft Azure Storage Libraries for .NET under the specific version. You could invoke CloudBlobContainer.Exist() , then call CloudBlobContainer.Create() instead of CloudBlobContainer.CreateIfNotExists . But at this point, you need to wrap CloudBlobContainer.Create() with try-catch to capture exceptions (eg someone has created the resource with the same name,etc.) by yourself.

Additionally, you could leverage ILSpy or ReSharper to retrieve more detailed implementation about CloudBlobContainer.CreateIfNotExists .

The PUT request is triggered by container.CreateIfNotExists(), which should fail as expected when your container already exists. The whole code path works correctly and I don't think you need to worry anything.

The mechanism of container.CreateIfNotExists() is that Azure Storage Client Library will send a Put Container request to server, and swallow the error if it's 409 (Conflict) since it indicates the container already exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM