I have a controller in ASP .Net MVC (dotnet core 2.1) and I'm trying to return a zip file to the user.
[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;
}
When I visit the URI in Chrome, it seemingly downloads the zip file however, when I try to open it, Windows claims the file is invalid.
If I make the request in Fiddler, I can see that the server returns a blob of base 64. If I manually decode this base 64 and save the resulting bytes, it results in a valid zip file.
Here are all of the response headers (some redacted for reasons).
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]
Can anyone suggest what I might be doing wrong?
Any advice much appreciated.
Thanks,
Steve.
memoryStreamcontain the base64 encoded content?application/zipandapplication/octet-stream.using. Wrap it in atry/finallyif desired.filenameis there twice in the headers. That happens on your local PC?