Search code examples
c#asp.net-mvcrazorstreamingdotnetzip

Add dynamic FileName to DotNetZip MVC Extension Method


I'm using the DotNetZip MVC Extension Method example for adding multiple files (I am getting mine from a repository) but I can't seem to figure out how to pass my own fileName into the extension method and get a result other than "file.zip", which is their examples hardcoded default value. Below is my CSHTML code, my Action and my Extension Method. You will see in my Action that I have a filename I want to use.

I'm embarrassed to show my attempts, but you can see what I'd like to use for my filename. Any suggestions?

CSHTML (Razor)

<a href="/Renders/Download/@renders.RenderId">Download</a>

Controller Action:

    public ActionResult Download(int id)
    {
        var allImages = _repo.GetImagesByRender(id);
        var list = new List<String>();

        var render = _repo.GetRenderById(id);
        var fileName = render.Select(r => r.Title);

        foreach (var img in allImages)
        {
            list.Add(Server.MapPath("~/ImageStore/" + img.Path));
        }

        return new ZipResult(list);
    }

The Extension Method

public class ZipResult : ActionResult
{
    private IEnumerable<string> _files;
    private string _fileName;

    public string FileName
    {
        get
        {
            return _fileName ?? "file.zip";
        }
        set { _fileName = value; }
    }

    public ZipResult(params string[] files)
    {
        this._files = files;
    }

    public ZipResult(IEnumerable<string> files)
    {
        this._files = files;
    }

    public override void ExecuteResult(ControllerContext context)
    {   // using clause guarantees that the Dispose() method is called implicitly!
        using (ZipFile zf = new ZipFile())
        {
            zf.AddFiles(_files, false, "");
            context.HttpContext.Response
                   .ContentType = "application/zip";
            context.HttpContext.Response
                   .AppendHeader("content-disposition", "attachment; filename=" + FileName);

            zf.Save(context.HttpContext.Response.OutputStream);
        }
    }

} 

As for the Repo, it returns the proper Images collection associated by RenderId and also the propper Render so that I can use the Render Title as the fileName, but how would I modify the ACtion and the Extended Action Method in order to make my zipFile have the proper name?


Solution

  • You can add another constructor to your ZipResult class:

    ...
    public ZipResult(IEnumerable<string> files, string fileName)
    {
        this._files = files;
        this._fileName = fileName;
    }
    ...
    

    Then in controller you cne use it:

    ...
    return new ZipResult(list, "test.zip");