thomvlau
thomvlau

Reputation: 602

Zip file not downloading after zip was correctly filled but contentlength is empty

On my page I currently have the following: a webgrid with some invoices, for every invoice I have a checkbox, for every invoice I have a pdf-Icon to view the pdf in the browser or to download the pdf.

What I'm trying to accomplish is that the user has the possibility to check some invoices and hit the button below to download these invoices as a ZIP file.

When the button is clicked an jquery function is called, this function makes an AJAX-call to my ASP.net. I pass an arrayparameter of the corresponding ID's of the invoice.

jQuery - Ajax-call

$("#download").click(function () {
    var idArray = [];
    $("input[type=checkbox]").each(function () {

        if (this.checked)
        {
            idArray.push($(this).val());
        }
    });

    $.ajax({
        traditional: true,
        type: "GET",
        url: "/Invoices/downloadInvoices",
        data: { idArray: idArray },
        error: function () {
            alert("error");
        }
    }).done(function (data) {
        console.log("succes download function");
    });
});

This function works as expected, in my controller I receive the array. The next step is to get the corresponding files (base64 from database) convert these files and put these file into the ZIP. This works aswell, when i check the entries of the ZIP it has the right content.

Controller

    public ActionResult downloadInvoices(string[] idArray) 
    {
        MemoryStream outputStream = new MemoryStream();

        outputStream.Seek(0, SeekOrigin.Begin);

        using (ZipFile zip = new ZipFile()) 
        {
            foreach (string id in idArray) 
            {
                string json = rest.getDocumentInvoice(Convert.ToInt32(id));
                byte[] file = json.convertJsonToFile();
                zip.AddEntry("invoice" + id + ".pdf", file);
            }
            zip.Save(outputStream);
        }

        outputStream.WriteTo(Response.OutputStream);
        Response.AppendHeader("content-disposition", "attachment; filename=invoices.zip"); 

        Response.ContentType = "application/zip";
        //return File(outputStream, "application/zip", fileDownloadName:"invoices.zip"); -- DIDN'T WORK

        return new FileStreamResult(outputStream, "application/zip") { FileDownloadName = "invoices" };
    }

The last step I need is that the user sees the popup to save the zip-file but this doesn't happen. When I check my debugger the ajaxcall is completed succesfully. When I check the debugger (headers) I see the request but the response headers shows contentlength : 0.

What am I missing, couldn't find any solution on the net. Hope u can help me.

Thanks in advance

EDIT

{ FileDownloadName = "invoices" }

When this piece of code is deleted my contentlength isn't 0 anymore. But how can this file now be downloaded? The content the request is sending looks like the file but the popup to download the file isn't showing.

Upvotes: 1

Views: 1672

Answers (3)

recineshto
recineshto

Reputation: 128

Maybe I am wrong, but to me it looks like you need to rewind memory stream to beginning before you can sent its content, add one

outputStream.Seek(0, SeekOrigin.Begin);

before

outputStream.WriteTo(Response.OutputStream);

and try again :)

Upvotes: 0

andres descalzo
andres descalzo

Reputation: 14967

the zip file should be in data, the parameter of the event done, but as you're making an ajax query you will not see the popup for the user to download the file.

you can do two option in my expediency, the first is to send data with a form and in the attribute target put the value _blank to go to a new window or put for example mywindow and do this with window.open:

window.open('about:blank', 'mywindow');

the second option is to send data by ajax and receive a json object with ok or failure, if the action is ok save the file somewhere and on ok response you can send an id and then do something similar to the first option but making sure that file was generated fine, and in other action in your controller recibe the id and send the zip file.

Upvotes: 1

thomvlau
thomvlau

Reputation: 602

Ajax doesn't allow to download files. This is for security reasons.

So to download files, don't use AJAX. Create an anchor pointing to your server side script that serves the file to be downloaded.

Upvotes: 0

Related Questions