Reputation: 33988
I have a REST API which must get a file from a remote URL in AWS servers. The file is downloaded but when I try to open it, it shows nothing, like corrupted.
No exceptions are thrown
the code is this
[HttpPost]
[Route("api/[controller]/UploadFileToAzureStorage")]
public async Task<IActionResult> GetFile([FromBody]PDF urlPdf)
{
string localFilePath = CreateTemporaryFile(urlPdf.urlPDF);
// Create storage account
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageAccount);
// Create a blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Get a reference to a container named "mycontainer."
CloudBlobContainer container = blobClient.GetContainerReference(UploaderStorage.Container);
// Get a reference to a blob named "myblob".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob");
// Create or overwrite the "myblob" blob with the contents of a local file
// named "myfile".
using (var fileStream = System.IO.File.OpenRead(localFilePath))
{
await blockBlob.UploadFromStreamAsync(fileStream);
}
return Ok();
}
/// <summary>
/// Creates temporary file
/// </summary>
/// <param name="urlPdf">PDF URL</param>
/// <returns>Returns path of the new file</returns>
private string CreateTemporaryFile(string urlPdf)
{
Uri uri = new Uri(urlPdf);
string filename = default(string);
//if (uri.IsFile)
//{
filename = System.IO.Path.GetFileName(uri.LocalPath);
//}
try
{
using (var client = new HttpClient())
{
using (HttpResponseMessage response =
client.GetAsync(urlPdf, HttpCompletionOption.ResponseHeadersRead).Result)
{
response.EnsureSuccessStatusCode();
using (Stream contentStream = response.Content.ReadAsStreamAsync().Result, fileStream = new FileStream(@"\\pc030\TemporaryPDF\"+ filename,
FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
var buffer = new byte[8192];
var isMoreToRead = true;
do
{
var read = contentStream.ReadAsync(buffer, 0, buffer.Length).Result;
if (read == 0)
{
isMoreToRead = false;
}
else
{
fileStream.WriteAsync(buffer, 0, read);
}
}
while (isMoreToRead);
}
}
}
return @"\\pc030\TemporaryPDF\" + filename;
}
catch(Exception ex)
{
throw ex;
}
}
Upvotes: 0
Views: 1414
Reputation: 120400
response.Content.ReadAsStreamAsync().Result
and contentStream.ReadAsync(buffer, 0, buffer.Length).Result
are a deadlock-bomb waiting to go off in your code.
Never block by waiting on Task.Result
in UI code or server code unless you fully understand the implications of doing so.
Both server and UI use a special SynchronizationContext
that schedules the async continuation back to the calling thread. When that same thread is already hung, waiting for Result
, everything can lock-up.
Read and digest:
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Your CreateTemporaryFile
method should be marked async
and you should be await
ing those calls.
So, to your problem. You're calling fileStream.WriteAsync(buffer, 0, read)
without await
ing the Task's completion. On the (at least) last write, the stream will be disposed before the write is complete, with predicable results.
Adopt async
properly or don't use it at all. There's no half-way house.
Upvotes: 9