#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 в комментариях.