【问题标题】:C# MVC/API - Return an image from Amazon S3 for my API CallC# MVC/API - 从 Amazon S3 为我的 API 调用返回图像
【发布时间】:2019-02-24 00:30:45
【问题描述】:

我正在使用 .net 核心从私有 Amazon S3 存储桶上传和检索图像。

我能够成功上传它,甚至在我从 S3 下载它之后查看它,但是当我有点不确定如何将流/响应返回给客户端以进行实际的 API 调用时(对于现在的示例我只是尝试使用 Postman/Fiddler 代理工具从我的 API 取回图像)

我的 S3 检索流的代码:

///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;
    }

所以现在在我的控制器中,我有以下操作:

   [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");
    }

当我使用 Postman 拨打电话时,它会返回一个小空白框(如果您尝试返回图像,您会看到该框,但它不是有效图像或以某种方式为 null)。

现在我正在使用 Postman,但理想情况下我想要一个应用来呈现这张图片。

任何想法我做错了什么?我尝试过使用 base64 编码和其他东西,但似乎没有任何效果。

谢谢!

【问题讨论】:

    标签: c# asp.net-mvc asp.net-web-api amazon-s3 asp.net-core


    【解决方案1】:

    这样您就可以从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);
        }
    }
    

    然后 - 将此流返回为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");
    }
    

    【讨论】:

    • 谢谢!我非常感谢您不仅帮助我,甚至在我自己的函数中输入代码以使其工作。我不需要改变任何东西。 TYSM :)
    • 对您的代码进行额外改进:我建议 1) 添加密钥格式检查(检查错误的斜杠并在需要时用正确的斜杠替换它们)2) 在 catch 块中 - exception 很可能会是AggregateException你应该注意扁平化它https://stackoverflow.com/questions/22872995/flattening-of-aggregateexceptions-for-processing 3)添加预检查存储文件是否存在
    • 既然可以将它交给return File(streamFromS3),为什么还要复制到MemoryStream?
    • 是的,您也可以不将其复制到内存@Alex
    猜你喜欢
    • 2015-10-29
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 2012-05-04
    • 2022-01-12
    • 2013-11-10
    • 1970-01-01
    • 2017-09-11
    相关资源
    最近更新 更多