Reputation: 9305
I upload attachments to an Azure Blob storage. I also create a SAS-Token when uploading; I retrieve the unique URL, send it to the browser where it is opened immediatly.
When I do this I often (but not always) retrieve a 404 that this resource does not exist. When refreshing the page just a few seconds later it is retrieved correctly.
So it seems that I am "too fast" after uploading the attachment. Is there a way to wait until Azure is ready to serve the attachment? I would have expected awaiting the call would be sufficient to achieve this.
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
};
}
The method GetInvoice
is called by REST and the response (containing the URL) returned to the browser where it is opened.
Upvotes: 2
Views: 602
Reputation: 136306
If you notice, you're not waiting for the upload operation to finish here:
_azureStorageRepository.UploadFile(invoiceFilename, file);
Please change this to:
await _azureStorageRepository.UploadFile(invoiceFilename, file);
And you should not see the 404 error. Azure Blob Storage is strongly consistent.
Also, change the UploadFile
method from public async void UploadFile
to public async Task UploadFile
as mentioned by @Fildor in the comments.
Upvotes: 3