I'm using .net core to upload and retrieve an image from a private Amazon S3 bucket.
I'm able to upload it successfully, and even view it after I download it from S3, however when I'm a bit unsure about how to return the stream/response back to the client for the actual API call (for example right now I'm just trying to use Postman/Fiddler proxy tools to get back the image from my API)
My code for S3 to retrieve the stream:
///Retrieve my image from my bucket
public async Task<string> ReadObjectData(MediaFolder key, String fileName)
{
string responseBody = "";
IAmazonS3 client;
using (client = new AmazonS3Client(accessKey, accessSecret, endpoint))
{
Amazon.S3.Model.GetObjectRequest request = new Amazon.S3.Model.GetObjectRequest
{
BucketName = bucket,
Key = key + "/" + fileName,
};
using (GetObjectResponse response = await client.GetObjectAsync(request))
using (Stream responseStream = response.ResponseStream)
using (StreamReader reader = new StreamReader(responseStream))
{
string title = response.Metadata["x-amz-meta-title"];
responseBody = reader.ReadToEnd();
}
}
return responseBody;
}
So now in my controller, I have the following action:
[HttpGet("ProfilePic")]
public async Task<IActionResult> GetProfilePicture()
{
var user = await GetUserFromBearerToken();
//Retrieve
var utf8ImageResponse = await _fileService.ReadObjectData(MediaFolder.Profiles, user.ProfileImageFileName);
//To return a file as a stream
var imageBytes = System.Text.Encoding.UTF8.GetBytes(utf8ImageResponse);
//Return the image, which I'll hardcode as jpeg for a test
return File(imageBytes, "image/jpeg");
}
When I make the call using Postman, it returns a little blank box (the box you'd see if you tried to return an image, but it wasn't a valid image or null in some way).
Right now I'm using Postman but ideally I'd want an app to present this image.
Any ideas what I'm doing wrong? I tried messing around with base64 encoding and other things but nothing seems to work.
Thanks!
This way you can retrieve the file as stream from S3
storage
public async Task<Stream> ReadObjectData(MediaFolder key, String fileName)
{
try
{
using (var client = new AmazonS3Client(accessKey, accessSecret, endpoint))
{
var request = new GetObjectRequest
{
BucketName = bucket,
Key = key + "/" + fileName
};
using (var getObjectResponse = await client.GetObjectAsync(request))
{
using (var responseStream = getObjectResponse.ResponseStream)
{
var stream = new MemoryStream();
await responseStream.CopyToAsync(stream);
stream.Position = 0;
return stream;
}
}
}
}
catch (Exception exception)
{
throw new Exception("Read object operation failed.", exception);
}
}
And then - return this stream as FileStreamResult
:
[HttpGet("ProfilePic")]
public async Task<IActionResult> GetProfilePicture()
{
var user = await GetUserFromBearerToken();
Stream imageStream = await _fileService.ReadObjectData(MediaFolder.Profiles, user.ProfileImageFileName);
Response.Headers.Add("Content-Disposition", new ContentDisposition
{
FileName = "Image.jpg",
Inline = true // false = prompt the user for downloading; true = browser to try to show the file inline
}.ToString());
return File(imageStream, "image/jpeg");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With