Reputation: 561
I'm trying to upload a file to an AWS S3 bucket using a pre-signed URL. I'm using the following code:
Uri output = GetPresignedUrl(amazonS3, awsPresignedUrlOptions);
using (FileStream tempInFileStream = new(tempFileName.LocalPath, FileMode.Open))
{
using (HttpClient httpClient = new())
{
StreamContent streamContent = new(tempInFileStream);
HttpResponseMessage response = httpClient
.PutAsync(output, streamContent)
.Result;
response.EnsureSuccessStatusCode();
}
}
The first line of code gets the pre-signed URL, and I'm sure it works because if I use the URL in Postman to try a PUT, it works fine (i.e., I'm able to upload the file).
My problem is in the HttpResponseMessage response = httpClient.PutAsync(output, streamContent).Result;
line: executing the line, the software seems to do absolutely nothing and, after a period, raise an exception for the timeout.
Any suggestion?
EDIT
As suggested by @Yevhen Cherkes, I tried to use async code:
private static async void UploadAsync(Uri tempFileName, Uri output)
{
try
{
using (FileStream tempInFileStream = new(tempFileName.LocalPath, FileMode.Open))
{
using (HttpClient httpClient = new())
{
StreamContent streamContent = new(tempInFileStream);
HttpResponseMessage response = await httpClient
.PutAsync(output, streamContent);
response.EnsureSuccessStatusCode();
}
}
}
catch (Exception e)
{
throw e;
}
}
Called with this code:
Thread t = new Thread(() => UploadAsync(tempFileName, output));
t.Start();
t.Join();
The main thread correctly starts the sub-thread and waits to join, but when I tried to run the line HttpResponseMessage response = await httpClient.PutAsync(output, streamContent);
, execution immediately jumps to the line after t.Join();
with no errors or exceptions.
What can be done?
Regards.
Upvotes: 0
Views: 4804
Reputation: 561
Thank you to Yenhen Cherkes for the suggestion. Following the code that works for me.
The method is very simple:
private static async Task UploadAsync(Uri tempFileName, Uri output)
{
try
{
using (FileStream fileStream = File.OpenRead(tempFileName.LocalPath))
{
HttpClient httpClient = new HttpClient();
StreamContent streamContent = new(fileStream);
await httpClient.PutAsync(output, streamContent);
}
}
catch (Exception e)
{
throw e;
}
}
To call this method use:
output = GetPresignedUrl(amazonS3, awsPresignedUrlOptions);
await UploadAsync(tempFileName, output);
where output
is the pre-signed URI and tempFileName
is the URI to the local resource.
Upvotes: 0