简体   繁体   English

Azure Blob下载(GET)导致PUT请求失败

[英]Azure Blob download(GET) causes failed PUT request

I'm downloading files from the Azure blob to display them to my users. 我正在从Azure blob下载文件以将其显示给我的用户。 The files are just resumes in doc/docx/pdf format. 这些文件只是以doc / docx / pdf格式恢复。 This used to work until few days ago, and only thing I did was update Azure SDK, so it might be the reason. 这曾经在几天前工作,我所做的只是更新Azure SDK,所以这可能就是原因。 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: GetContainer方法定义如下:

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. 截至昨天,我一直在Azure Application Insights中看到失败的依赖性调用。 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. 每次下载文件时,都会执行GET请求,但同时由于某种原因也会执行PUT请求,并且失败。 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... 调用该方法,下载文件,然后调用该PUT请求......

在此输入图像描述

Why is this PUT request being created, and how to solve this behavior, it's driving me crazy. 为什么要创建此PUT请求,以及如何解决此问题,这让我发疯。 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. 有趣的是,就我所见,一切正常,所有这些都发生在我所有上传和下载blob的调用中。

As mentioned in the release notes about Microsoft Azure Storage Libraries for .NET for version 8.0.0: 正如关于Microsoft Azure存储库for .NET for 8.0.0的发行说明中所述:

CreateIfNotExists methods will now only do one REST call instead of two. CreateIfNotExists方法现在只执行一次REST调用而不是两次。

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: 在8.0.0版之前, CreateIfNotExists将检查目标是否存在,然后创建资源(如果不存在),如下所示:

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. 在此版本8.0.0之后, CreateIfNotExists将直接调用create方法并使用try-catch包装此操作以捕获异常。

In summary, this issue dues to the changes of the Microsoft Azure Storage Libraries for .NET under the specific version. 总之,此问题归因于特定版本下Microsoft Azure存储库for .NET的更改。 You could invoke CloudBlobContainer.Exist() , then call CloudBlobContainer.Create() instead of CloudBlobContainer.CreateIfNotExists . 您可以调用CloudBlobContainer.Exist() ,然后调用CloudBlobContainer.Create()而不是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. 但此时,您需要使用try-catch包装CloudBlobContainer.Create()以捕获异常(例如某人已创建具有相同名称的资源等)。

Additionally, you could leverage ILSpy or ReSharper to retrieve more detailed implementation about CloudBlobContainer.CreateIfNotExists . 此外,您可以利用ILSpyReSharper来检索有关CloudBlobContainer.CreateIfNotExists更详细的实现。

The PUT request is triggered by container.CreateIfNotExists(), which should fail as expected when your container already exists. PUT请求由container.CreateIfNotExists()触发,当容器已存在时,它应按预期失败。 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. container.CreateIfNotExists()的机制是Azure存储客户端库将向服务器发送放置容器请求,如果它是409(冲突)则吞下错误,因为它表明容器已存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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