【问题标题】:PDF Uploaded via AWS API Gateway getting corrupted通过 AWS API Gateway 上传的 PDF 已损坏
【发布时间】:2020-08-10 04:28:10
【问题描述】:

我正在尝试使用已部署到 AWS API 网关的 C# Web API 通过 Web 表单将 PDF 上传到 S3 存储桶。

这是我的代码:

 private static IAmazonS3 s3Client;


        public static async Task<string> UploadS3FileAsync(string bucketName, IFormFile file, string keyName)  
        {
            try
            {  

                s3Client = new AmazonS3Client();      
                var fileTransferUtility =  new TransferUtility(s3Client);

                //Upload data from a type of System.IO.Stream.
                var stream = file.OpenReadStream();
                var length = (int)stream.Length;
                byte[] data = new byte[length];

                stream.Read(buffer: data, offset: 0, count: length);

               var fileTransferUtilityRequest = new TransferUtilityUploadRequest

                {
                    BucketName = bucketName,
                    InputStream = stream,
                    StorageClass = S3StorageClass.Standard,
                    ContentType = "application/pdf",
                    PartSize = 6291456, // 6 MB.
                    Key = keyName,
                    CannedACL = S3CannedACL.NoACL
                };

                await fileTransferUtility.UploadAsync(fileTransferUtilityRequest); 

                return "success";

            }
            catch (AmazonS3Exception e)
            {
                throw e;
                //Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                throw e;
                //Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }

        }

当我在本地运行该过程时,这非常有效,但是当我将 API 部署到网关时,虽然上传到存储桶中的 PDF 已损坏并且比原始文件大。

我尝试了各种方法,例如在 API 网关上设置二进制媒体类型、创建流的各种类型。我确定它与编码有关,但我不确定下一步该去哪里。任何帮助将不胜感激。

【问题讨论】:

  • 出于兴趣,stream.Read 行的目的是什么?我认为 S3 库可能会为您执行此操作,但通常您应该在重用流之前回到起点。
  • 嗨,约翰。感谢您的回复。我尝试了许多不同的方法来创建流,这是我最近的尝试。我会尝试删除那条线,看看它是否有什么不同。
  • 如果您在 S3 上获得的对象比您上传的更大,我不能 100% 确定它是否会有所帮助。这似乎很奇怪。
  • 是的,我试过了,结果是一样的。原始 PDF 大约 116kB,上传的文档超过 200kB。当我在 Chrome 中打开文档时,它显示“无法加载 PDF 文档”我试图检查 PDF,它似乎确实有一些有效的 PDF 数据,但我很难理解为什么它不能正确上传.
  • 运气好可以解决这个问题吗?面对同样的事情。有一种感觉 API Gateway 是罪魁祸首。我已尝试设置“二进制媒体类型”设置(和部署),但似乎仍然无法正常工作。

标签: c# amazon-web-services api amazon-s3


【解决方案1】:

您是否在设置选项卡中配置了“二进制媒体类型”?

API Gateway 默认将所有请求负载视为文本数据,即非二进制数据,并对负载执行 base64 编码。您拥有的较大 PDF 应该是包含原始 PDF 的 base64 编码版本的文件。

参考:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html

【讨论】:

  • 谢谢,我去看看。我最终选择了获取预签名 URL 以允许客户端上传,并且运行良好。参考:medium.com/@aidan.hallett/…
【解决方案2】:

这就是为我解决的问题:

https://github.com/aws/aws-lambda-dotnet/issues/635

  1. 在二进制媒体类型标题下的设置中,为multipart/form-data 创建一个条目。
  2. 使用以下配置创建一个新模型。
{
   "$schema": "http://json-schema.org/draft-04/schema#",
   "title": "MediaFileUpload",
   "type": "object",
   "properties": {
   "file": { "type": "string" }
  }
}
  1. 修改方法请求步骤,在“请求正文”下添加一个条目,使用模型作为multipart/form-data的内容类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2015-11-14
    • 2022-08-17
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多