Reputation: 6786
I am trying to create a zip file with SharpZipLib from files stored on Azure Storage. Unfortunately I am not able to return them because the Api always returns a Json:
{"Version":{"Major":1,"Minor":1,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1},"Content":{"Headers":[{"Key":"Content-Disposition","Value":["attachment; filename=Documents.zip"]},{"Key":"Content-Type","Value":["application/octet-stream"]},{"Key":"Content-Length","Value":["498"]}]},"StatusCode":200,"ReasonPhrase":"OK","Headers":[],"RequestMessage":null,"IsSuccessStatusCode":true}
The zipping should work which I use, however I am not sure if everything is correct since I was never able to see the file.
This is the code for zipping the files and returning the zip file:
[HttpGet("DownloadFiles")]
public async Task<HttpResponseMessage> DownloadFiles(string invoiceNr, List<string> fileNames)
{
List<CloudBlockBlob> blobs = _documentService.GetBlobs(invoiceNr, fileNames);
MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
foreach (CloudBlockBlob blob in blobs)
{
using (MemoryStream blobStream = new MemoryStream())
{
await blob.DownloadToStreamAsync(blobStream);
ZipEntry newEntry = new ZipEntry(blob.Name);
newEntry.DateTime = DateTime.Now;
zipStream.PutNextEntry(newEntry);
StreamUtils.Copy(blobStream, zipStream, new byte[4096]);
zipStream.CloseEntry();
}
}
zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.
zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream.
outputMemStream.Position = 0;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(outputMemStream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "Documents.zip";
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentLength = outputMemStream.Length;
return result;
}
Is it the wrong way of returning a file from WebAPi? Am I doing something wrong in general?
Thanks in advance for the help.
Upvotes: 1
Views: 1093
Reputation: 5021
As you declare your web method as
public async Task<HttpResponseMessage> DownloadFiles(...)
ASP.NET Core treats HttpResponseMessage as model and your methods returns instance of this file serialized as JSON. The correct version of this method is
public async Task<IActionResult> DownloadFiles()
{
...
return File(outputMemStream, "application/octet-stream", "Documents.zip");
}
Upvotes: 2