【问题标题】:Returning Binary Data from ASP .Net Core MVC using Serverless and AWS API Gateway使用无服务器和 AWS API 网关从 ASP .Net Core MVC 返回二进制数据
【发布时间】:2020-01-18 09:09:25
【问题描述】:

我在 ASP .Net MVC (dotnet core 2.1) 中有一个控制器,我正在尝试将一个 zip 文件返回给用户。

[HttpGet]
public async Task<ActionResult> GetLogFiles([FromQuery] string date, 
                                            [FromQuery] string startTime, 
                                            [FromQuery] string endTime)
{
    var decryptedFiles = new Dictionary<string, string>();

    // Code to get log files, decrypt them and add to dictionary

    using (var memoryStream = new MemoryStream())
    {
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            foreach (var (name, data) in decryptedFiles)
            {
                _logger.LogInformation($"Adding {name}");

                var entry = archive.CreateEntry(name);

                using (var entryStream = entry.Open())
                {
                    using (var writer = new StreamWriter(entryStream, Encoding.GetEncoding("Windows-1252")))
                    {
                        writer.Write(data);
                    }
                }
            }
        }

        memoryStream.Seek(0, SeekOrigin.Begin);

        var rawData = memoryStream.ReadAll();

        var response = File(rawData, "application/zip", "logs.zip");

        return response;
    }
}

public static byte[] ReadAll(this Stream stream)
{
    var count = (int) stream.Length;

    var buffer = new byte[count];

    var offset = 0;

    while (offset < count)
    {
        var read = stream.Read(buffer, offset, count - offset);

        if (read == 0)
        {
            throw new EndOfStreamException();
        }

        offset += read;
    }

    return buffer;
}

当我在 Chrome 中访问 URI 时,它似乎会下载 zip 文件,但是当我尝试打开它时,Windows 声称该文件无效。

如果我在 Fiddler 中发出请求,我可以看到服务器返回一个 base 64 的 blob。如果我手动解码这个 base 64 并保存结果字节,它会生成一个有效的 zip 文件。

这里是所有响应标头(一些因原因而编辑)。

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 508
Connection: keep-alive
Date: Tue, 17 Sep 2019 14:04:43 GMT
x-amzn-RequestId: [REDACTED]
Content-Disposition: attachment; filename=logs.zip; filename*=UTF-8''logs.zip
Strict-Transport-Security: max-age=2592000
x-amzn-Remapped-Content-Length: 381
x-amz-apigw-id: [REDACTED]
X-Amzn-Trace-Id: [REDACTED]
X-Cache: Miss from cloudfront
Via: 1.1 [REDACTED]
X-Amz-Cf-Pop: [REDACTED]
X-Amz-Cf-Id: [REDACTED]

谁能建议我做错了什么?

非常感谢任何建议。

谢谢,

史蒂夫。

【问题讨论】:

  • @Stevo 可能是一个愚蠢的问题,因为我确定您已经检查过了,但我想验证一下:memoryStream 是否包含 base64 编码的内容?
  • application/zipapplication/octet-stream 都试过了。
  • 啊,您传入该方法的流将由框架处理,因此只需将其从using 中删除即可。如果需要,将其包裹在 try/finally 中。
  • 奇怪的是 filename 在标题中出现了两次。这发生在您的本地 PC 上?
  • 正确破解它。 @mjwills 该链接为我指明了正确的方向。我将在答案中发布实际详细信息,以便帮助遇到此问题的其他人。

标签: c# aws-lambda aws-api-gateway serverless asp.net-core-mvc-2.1


【解决方案1】:

因此,感谢用户 mjwills 发布 this 链接,这似乎是 API Gateway 对二进制媒体类型的处理。

下一个障碍是我正在使用无服务器,因此无法在 CloudFormation 中设置 this

在serverless.yml中的配置方式如下:

provider:
  apiGateway:
    binaryMediaTypes:
      - "application/zip"

还不完全在那里。最后一个难题是在请求中添加一个标头。

Accept: application/zip

【讨论】:

    猜你喜欢
    • 2021-05-11
    • 2018-11-20
    • 2018-06-16
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    相关资源
    最近更新 更多