2017-01-11 6 views
0

Я загружаю файлы из Azure blob, чтобы отобразить их для моих пользователей. Файлы только возобновляются в формате doc/docx/pdf. Это работало до нескольких дней назад, и только я сделал обновление Azure SDK, так что это может быть причиной. метод вызывается на стороне клиента, который заканчивается вызовом метода, как это:Azure Blob download (GET) вызывает неудачный запрос PUT

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 определяется следующим образом:

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); 
} 

По состоянию на вчера, я продолжаю видеть в Azure Application Insights неудачные вызовы зависимостей. Не ошибки, а просто неудачные зависимости. Каждый раз, когда файл загружается, выполняется запрос GET, но в то же время PUT-запрос также выполняется по какой-либо причине, и он терпит неудачу. На изображении ниже вы можете увидеть журнал Insights для этой ошибки. Каждый выглядит одинаково. Вызывается метод, файл загружен, а затем этот запрос PUT называют ...

enter image description here

Почему этот запрос PUT создается, и как решить эту проблему, это сводит меня с ума. Интересно также, что все работает отлично, насколько я вижу, и это происходит во всех моих загружаемых и загружаемых звонках на blobs.

+0

Почему вы возвращаете утилиту 'fileStream'? Разве это не вызовет проблемы? Что вы делаете с этим значением? –

+0

Я возвращаю его и считываю массив байтов из него с помощью метода ToArray(). Байт-массив по-прежнему доступен после закрытия/удаления потока (http://stackoverflow.com/questions/3981253/is-calling-memorystream-toarray-dangerous-after-disposing) –

ответ

3

Как уже упоминалось в release notes о Microsoft Azure Storage Libraries for .NET для версии 8.0.0:

CreateIfNotExists методы теперь будут делать только один вызов REST вместо двух.

Вот мой тест, вы можете обратиться к нему для лучшего понимания этого изменения:

До версии 8.0.0, CreateIfNotExists бы проверить существование цели, а затем создать ресурс, если не существует следующим образом:

Хотя после этой версии 8.0.0, CreateIfNotExists будет вызывать метод создания непосредственно и обернуть эту операцию с try-catch захватить исключение.

В целом, этот вопрос сборы к изменениям Azure библиотек хранения Microsoft для .NET под конкретной версии. Вы можете вызвать CloudBlobContainer.Exist(), а затем позвонить CloudBlobContainer.Create() вместо CloudBlobContainer.CreateIfNotExists. Но на данный момент вам нужно обернуть CloudBlobContainer.Create()try-catch, чтобы фиксировать исключения (например, кто-то создал ресурс с тем же именем и т. Д.) Самостоятельно.

Кроме того, вы можете использовать ILSpy или ReSharper, чтобы получить более подробную информацию об CloudBlobContainer.CreateIfNotExists.

+0

Спасибо, Брюс, это отвечает на мой вопрос. Мне просто не нравится видеть кучу ошибок в моей консоли, поэтому я думаю, что я изменю свой код на отдельные вызовы. –

+0

Никакой попытки/уловки не требуется. Если Exists() возвращает false, то вызовите CreateIfNotExists(). Но также подумайте об избежании полного вызова. Если контейнер не существует, то blob тоже не работает, так зачем делать дополнительную поездку туда и обратно? –

0

Запрос PUT запускается контейнером.CreateIfNotExists(), который должен завершиться неудачно, если ожидается, когда контейнер уже существует. Весь путь кода работает правильно, и я не думаю, что вам нужно что-то беспокоиться.

Механизм container.CreateIfNotExists() заключается в том, что клиентская библиотека Azure Storage отправит запрос Put Container на сервер и проглотит ошибку, если это 409 (конфликт), поскольку указывает, что контейнер уже существует.

Смежные вопросы