404 в течение небольшого периода времени после загрузки файла в хранилище больших двоичных объектов Azure

#c# #azure

Вопрос:

Я загружаю вложения в хранилище больших двоичных объектов Azure. Я также создаю SAS-токен при загрузке; Я получаю уникальный URL-адрес, отправляю его в браузер, где он немедленно открывается.

Когда я делаю это, я часто (но не всегда) получаю 404, что этот ресурс не существует. При обновлении страницы всего через несколько секунд она будет восстановлена правильно.

Поэтому кажется, что я «слишком быстр» после загрузки вложения. Есть ли способ дождаться, пока Azure не будет готова обслуживать вложение? Я ожидал, что ожидания звонка будет достаточно для достижения этой цели.

 public async void UploadFile(string filename, byte[] filecontent)
{
    var containerClient = _blobServiceclient.GetBlobContainerClient("attachments");
    var blobClient = containerClient.GetBlobClient(filename);
    
    using (var stream = new MemoryStream(filecontent))
    {
      await blobClient.UploadAsync(stream, new BlobHttpHeaders { ContentType = GetContentTypeByFilename(filename) });
    }
}


  public async Task<string> GetLinkForFile(string filename)
{
    var containerClient = _blobServiceclient.GetBlobContainerClient("attachments");
    
    var sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = containerName,
        BlobName = filename,
        Resource = "b",
        StartsOn = DateTime.UtcNow.AddMinutes(-1),
        ExpiresOn = DateTime.UtcNow.AddMinutes(5),
    };

    // Specify read permissions
    sasBuilder.SetPermissions(BlobSasPermissions.Read);

    var credentials = new StorageSharedKeyCredential(_blobServiceclient.AccountName, _accountKey);
    var sasToken = sasBuilder.ToSasQueryParameters(credentials);

    // Construct the full URI, including the SAS token.
    UriBuilder fullUri = new UriBuilder()
    {
        Scheme = "https",
        Host = string.Format("{0}.blob.core.windows.net", _blobServiceclient.AccountName),
        Path = string.Format("{0}/{1}", containerName, filename),
        Query = sasToken.ToString()
    };

    return fullUri.ToString();
}



public async Task<Document> GetInvoice(byte[] invoiceContent, string invoiceFilename)
{
    string filePath = await GetLinkForFile(invoiceFilename);
    UploadFile(invoiceFilename, file);
    
    return new Document()
    {           
        Url = filePath
    };  
}
 

Метод GetInvoice вызывается REST, и ответ (содержащий URL-адрес) возвращается в браузер, в котором он открыт.

Комментарии:

1. Вероятно, это связано с тем, что вы не ожидаете завершения операции загрузки.

2. public async void UploadFile(string filename, byte[] filecontent) наверное public async Task ... , так и должно быть.

3. но есть «ОЖИДАНИЕ blobclient.upload…» ?

4. Это внутри. Я думаю, что вам нужно дождаться всех асинхронных операций.

5. Это означает только то, что его ждут в этом контексте . Не в контексте вызова.

Ответ №1:

Если вы заметили, вы не ждете завершения операции загрузки здесь:

 _azureStorageRepository.UploadFile(invoiceFilename, file);
 

Пожалуйста, измените это на:

 await _azureStorageRepository.UploadFile(invoiceFilename, file);
 

И вы не должны видеть ошибку 404. Хранилище больших двоичных объектов Azure строго согласовано.

Кроме того, измените UploadFile метод с public async void UploadFile на public async Task UploadFile , как указано @Fildor в комментариях.