Returning Multiple Files from MVC Action

2019-01-11 20:17发布

问题:

So I've got an MVC 3 application that has a couple places where a text file gets generated and returned in an action using:

return File(System.Text.Encoding.UTF8.GetBytes(someString),
                 "text/plain", "Filename.extension");

and this works fabulously. Now i've got a situation where I'm trying to return a pair of files in a similar fashion. On the view, i have an action link like "Click here to get those 2 files" and i'd like both files to be downloaded much like the single file is downloaded in the above code snippet.

How can I achieve this? Been searching around quite a bit and haven't even seen this question posed anywhere...

回答1:

Building on Yogendra Singh's idea and using DotNetZip:

var outputStream = new MemoryStream();

using (var zip = new ZipFile())
{
    zip.AddEntry("file1.txt", "content1");
    zip.AddEntry("file2.txt", "content2");
    zip.Save(outputStream);
}

outputStream.Position = 0;
return File(outputStream, "application/zip", "filename.zip");


回答2:

I would advice to create a zip file to include both the files using steps(ALGORITHM):

  1. Create a Zip file and add the desired files into the zip
  2. Return the zip file having all desired files from the action

Java Syntax (Just for understanding)

      FileOutputStream fos = new FileOutputStream("downloadFile.zip");
      ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
      zos.putNextEntry(new ZipEntry("Filename1.extension"+));
      //write data in FileName1.extension
      zos.write(contentBuffer1, 0, len);

      zos.putNextEntry(new ZipEntry("Filename2.extension"));
      //write data in FileName2.extension
      zos.write(contentBuffer2, 0, len);

      //write other files.....
      zos.close();

Once zip file is created, return the newly created zip file to download.

     return File("downloadFile.zip");

.DOT Net Equivalent using DotNetZip

     var os = new MemoryStream();

     using (var zip = new ZipFile())
     {
         //write the first file into the zip
         zip.AddEntry("file1.txt", "content1");

         //write the second file into the zip
         zip.AddEntry("file2.txt", "content2");

         //write other files.....
         zip.Save(os);
      }

      outputStream.Position = 0;
      return File(outputStream, "application/zip", "filename.zip");

Hope this helps!



回答3:

Sorry for bumping an old question but...

Another alternative would be to initiate multiple file downloads using JavaScript, and serve files in two different Action Methods on ASP.NET's side.

You're saying you have a link:

On the view, i have an action link like "Click here to get those 2 files"

So make this link like this:

<a href="#" onclick="downloadFile(url1); downloadFile(url2);">Click to get 2 files</a>
<script src="download.js"></script>

I'm using download.js script found here but you can find plenty of different other options, see this SO question: starting file download with JavaScript for example



回答4:

Look at this SO solution: MVC Streaming Zip File

The advantage of this solution is that it streams the file to the client.

I just implemented this solution a couple of days ago and it worked fantastic.