1

Hi im using the code in this blogpost :

https://blog.stephencleary.com/2016/11/streaming-zip-on-aspnet-core.html

In order to stream a zip file with .Net core. I made it work but since i did not add the content-length header in the response when i donwload the zip file, it won't show the download progress in chrome. Since i know in advance the zip file size I can actually set the content-length header, with the SetHeadersAndLog method https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.internal.fileresultexecutorbase.setheadersandlog?view=aspnetcore-2.0

but when i do so I have the following error :

System.InvalidOperationException: Response Content-Length mismatch: too many bytes written (144144633 of 144144627).

Any idea why the response is not the same length as the zip file ? Here's the code to serve the file:

     this._httpContext.Response.ContentType = "application/octet-stream";
            this._httpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
            this._httpContext.Response.ContentLength = estimatedFileSize;

            FileCallbackResult result = new FileCallbackResult(new MediaTypeHeaderValue("application/octet-stream"), estimatedFileSize, async (outputStream, _) =>
            {
                using (ZipArchive zip = new ZipArchive(outputStream, ZipArchiveMode.Create, false))
                {
                    foreach (string filepath in Directory.EnumerateFiles(existingDirectory.FullName, "*.*", SearchOption.AllDirectories))
                    {
                        string relativepath = filepath.Replace(existingDirectory.FullName + "\\", string.Empty);

                        ZipArchiveEntry zipEntry = zip.CreateEntry(relativepath, CompressionLevel.Fastest);
                        using (Stream zipstream = zipEntry.Open())
                        {
                            using (Stream stream = new FileStream(filepath, FileMode.Open))
                            {
                                await stream.CopyToAsync(zipstream);
                            }
                        }
                    }
                }
            })
            {
                FileDownloadName = $"{package.FileName}.zip",
            };
mxmissile
  • 11,464
  • 3
  • 53
  • 79
Francis Groleau
  • 344
  • 4
  • 14
  • 1
    Show where you are populating `estimatedFileSize`. – mxmissile Mar 04 '19 at 16:05
  • @mxmissile I have the zip file already on the disk (that i created the same way as i'm serving it here with the same CompressionLevel) I get it as a FileInfo with `Directory.EnumerateFile(filename).firstordefault()` then i check his length. – Francis Groleau Mar 04 '19 at 16:30
  • Have you tried just sending that file instead or recreating it? Different zip libs have different compression levels. – mxmissile Mar 04 '19 at 16:36

1 Answers1

4

You need to seek the stream back to the beginning.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Hai
  • 41
  • 4