MVC Zip Result
Sometimes you need to send to the user more than 1 file – or, maybe, the file is too large
The simplest way is : made a zip file that contains the others.
What do you need
1. SharpzipLib from http://www.icsharpcode.net/opensource/sharpziplib/ ( or download via NuGet in VS)
2. obtain the file(s) that you want as a string or as a byte[] – let’s say you have a byte[] to store in a str variable
3. make in your action something like that:
var fcr = new ZipResult("Export.xls", str); fcr.AddFile("readme.txt","this zip file contains .."); return fcr;
4. copy the following code in your asp.net mvc projects:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.IO; using ICSharpCode.SharpZipLib.Zip; using System.Text; namespace utilsResult { public class ZipResult : FileResult { private Dictionary<string, byte[]> content = new Dictionary<string, byte[]>(); public string FileNameZip; public ZipResult(string FileName, byte[] Contents) : base("application/octet-stream") { this.FileDownloadName = Path.GetFileNameWithoutExtension(FileName) + ".zip"; AddFile(FileName, Contents); } public void AddFile(string FileName, byte[] Contents) { content.Add(FileName, Contents); } public void AddFile(string FileName,string Contents, Encoding e = null) { if (e == null) e = ASCIIEncoding.ASCII; content.Add(FileName, e.GetBytes(Contents)); } protected override void WriteFile(HttpResponseBase response) { using (ZipOutputStream zos = new ZipOutputStream(response.OutputStream)) { zos.SetLevel(3); zos.UseZip64=UseZip64.Off; foreach (var item in content) { ZipEntry ze = new ZipEntry(item.Key); ze.DateTime = DateTime.Now; zos.PutNextEntry(ze); int count=item.Value.Length; zos.Write(item.Value, 0, count); } } } } }
5. future improvements:
Zip the file(s) in a dll project to made fully testable!
Good one.