How to download zip files in ASP Net Core
2 min readOct 9, 2018
Sections:
- Backend (building the zip file)
- Frontend (downloading the built zip file)
Backend
Creating the zip stream
Every file inside the zip will be a ZipItem
:
public class ZipItem
{
public string Name { get; set; }
public Stream Content { get; set; } public ZipItem(string name, Stream content)
{
this.Name = name;
this.Content = content;
} public ZipItem(string name, string contentStr, Encoding encoding)
{
// convert string to stream
var byteArray = encoding.GetBytes(contentStr);
var memoryStream = new MemoryStream(byteArray); this.Name = name;
this.Content = memoryStream;
}
}
Now zip all your files from the Action in the Controller, using this:
public static class Zipper
{
public static Stream Zip(List<ZipItem> zipItems)
{
var zipStream = new MemoryStream();
using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
foreach (var zipItem in zipItems)
{
var entry = zip.CreateEntry(zipItem.Name);
using (var entryStream = entry.Open())
{
zipItem.Content.CopyTo(entryStream);
}
}
} zipStream.Position = 0;
return zipStream;
}
}
The Controller’s Action
Instead of returning Ok()
or similar, you must return a File
:
[HttpGet()]
public IActionResult DownloadZip()
{
var zipStream = GetZipStream();
return File(zipStream, "application/octet-stream");
}
Frontend
Fetch the zip
downloadZip() {
fetch('api/zip')
.then((response) => {
if (response.status != 200) {
let errorMessage = "Error processing the request... (" + response.status + " " + response.statusText + ")";
throw new Error(errorMessage);
} else {
return response.blob();
}
})
.then((blob: any) => {
// !!! see next code block !!!
downloadData('geojsons.zip', blob);
})
.catch(error => {
console.error(error);
});
}
Download the zip
// Solution for big files (source: https://stackoverflow.com/a/25975345/831138)
downloadData(filenameForDownload: string, data: any) { var textUrl = URL.createObjectURL(data); var element = document.createElement('a');
element.setAttribute('href', textUrl);
element.setAttribute('download', filenameForDownload); element.style.display = 'none';
document.body.appendChild(element); element.click(); document.body.removeChild(element);}