【发布时间】: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/zip和application/octet-stream都试过了。 -
啊,您传入该方法的流将由框架处理,因此只需将其从
using中删除即可。如果需要,将其包裹在try/finally中。 -
奇怪的是
filename在标题中出现了两次。这发生在您的本地 PC 上? -
正确破解它。 @mjwills 该链接为我指明了正确的方向。我将在答案中发布实际详细信息,以便帮助遇到此问题的其他人。
标签: c# aws-lambda aws-api-gateway serverless asp.net-core-mvc-2.1