ASP MVC Download Zip Files

2019-02-20 06:09发布

问题:

i have a view where i put the id of the event then i can download all the images for that event..... here's my code

[HttpPost]
    public ActionResult Index(FormCollection All)
    {
        try
        {
            var context = new MyEntities();

            var Im = (from p in context.Event_Photos
                      where p.Event_Id == 1332
                      select p.Event_Photo);

            Response.Clear();

            var downloadFileName = string.Format("YourDownload-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HH_mm_ss"));
            Response.ContentType = "application/zip";

            Response.AddHeader("content-disposition", "filename=" + downloadFileName);

            using (ZipFile zipFile = new ZipFile())
            {
                zipFile.AddDirectoryByName("Files");
                foreach (var userPicture in Im)
                {
                    zipFile.AddFile(Server.MapPath(@"\") + userPicture.Remove(0, 1), "Files");
                }
                zipFile.Save(Response.OutputStream);

                //Response.Close();
            }
            return View();
        }
        catch (Exception ex)
        {
            return View();
        }
    }

The problem is that each time i get html page to download so instead of downloading "Album.zip" i get "Album.html" any ideas???

回答1:

In MVC, rather than returning a view, if you want to return a file, you can return this as an ActionResult by doing:

return File(zipFile.GetBytes(), "application/zip", downloadFileName);
// OR
return File(zipFile.GetStream(), "application/zip", downloadFileName);

Don't mess about with manually writing to the output stream if you're using MVC.

I'm not sure if you can get the bytes or the stream from the ZipFile class though. Alternatively, you might want it to write it's output to a MemoryStream and then return that:

 var cd = new System.Net.Mime.ContentDisposition {
     FileName = downloadFileName,
     Inline = false, 
};
Response.AppendHeader("Content-Disposition", cd.ToString());
var memStream = new MemoryStream();
zipFile.Save(memStream);
memStream.Position = 0; // Else it will try to read starting at the end
return File(memStream, "application/zip");

And by using this, you can remove all lines in which you are doing anything with the Response. No need to Clear or AddHeader.