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:

1
2
3
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:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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!