0

I have a controller action that creates a zip file and sends back to user for download. The problem is that the zip file gets created but it is empty. Somehow it's not writing the image files to the MemoryStream. I wonder what I am missing. If I write the zip file to the disk everything will work as expected, but I'd rather not save files to the disk if I can avoid it. This is what I have tried using dotnetzip:

public ActionResult DownloadGraphs()
    {
        var state = Session["State"];
        using (ZipFile zip = new ZipFile())
        {
            if (state == "IA")
            {
                zip.AddFile(Server.MapPath("~/Content/DataVizByState/FallGraphs/Watermarked/Fall_IA.jpg"), "");
                zip.AddFile(Server.MapPath("~/Content/DataVizByState/SpringGraphs/Watermarked/Spring_IA.jpg"), "");
            }
            MemoryStream output = new MemoryStream();
            zip.Save(output);
            output.Seek(0, SeekOrigin.Begin);
            var fileName = state + "Graphs.zip";
            return File(output, "application/zip", fileName);
        }
    }

This forces download in the view based on click of a button:

$('#graphDwnldBtn').click(function (evt) {
    window.location = '@Url.Action("DownloadGraphs", "DataSharing")';
})

Do I need to use StreamWriter or Reader or something? This is the first time I have ever attempted something like this and it's been cobbled together by reading various stackoverflow posts...

MKF
  • 426
  • 7
  • 24
  • Maybe it really is empty because the files were not found on disk. Can you verify the length of the MemoryStream instance in the debugger? If that has content then check the network tab in the browser to see what is being received (if that has content). – Igor Sep 26 '18 at 15:50
  • This is just a guess, but try calling `output.Flush();` after calling `zip.Save(outout);` – Craig W. Sep 26 '18 at 15:53
  • No luck with `flush` and `output.Length` = 22 so there's something in there. – MKF Sep 26 '18 at 15:56
  • @CraigW. - `MemoryStream` has no underlying device to flush to, any writes are done immediately. – Igor Sep 26 '18 at 15:57
  • @Igor I'm not exactly sure what I'm supposed to be looking at in the Network tab, but when I look at the response header it states a content-length of 22. – MKF Sep 26 '18 at 16:03
  • 2
    Are you sure the state is "IA" in all caps with no spaces? I.e - are you actually getting inside of that `if()`statement in your code? – Tommy Sep 26 '18 at 16:06
  • I've done a little testing. If the files you're trying to zip up don't exist a `FileNotFoundException` gets thrown when calling `Save` so that seems unlikely as the problem. My test is a console application rather than MVC but that shouldn't make any difference. After I call `Save` the memory stream has 570402 bytes in it. Perhaps try debugging the above code to make sure `output` has something in it. That would at least give some idea whether the problem was occurring later in the code. – Craig W. Sep 26 '18 at 16:07
  • 1
    @Tommy - Thank you! Stupid mistake on my part. I need to cast `state` to a string as the `Session["State"]` variable is actually an object, so my `if` statement wasn't working how I expected. – MKF Sep 26 '18 at 16:10

1 Answers1

0

Dumb mistakes: Session["State"] is an object, so the state variable was coming out as object instead of a string like I need it to be for my conditional statement to evaluate correctly. I cast state to a string to fix it. Fixed code:

public ActionResult DownloadGraphs()
    {
        var state = Session["State"].ToString(); 
        using (ZipFile zip = new ZipFile())
        {
            if (state == "IA")
            {
                zip.AddFile(Server.MapPath("~/Content/DataVizByState/FallGraphs/Watermarked/Fall_IA.jpg"), "");
                zip.AddFile(Server.MapPath("~/Content/DataVizByState/SpringGraphs/Watermarked/Spring_IA.jpg"), "");
            }
            MemoryStream output = new MemoryStream();
            zip.Save(output);
            output.Seek(0, SeekOrigin.Begin);
            var fileName = state + "Graphs.zip";
            return File(output, "application/zip", fileName);
        }
    }
MKF
  • 426
  • 7
  • 24