views:

28

answers:

2

Hi Guys,

OK, I've been pulling my hair out about this for ages. I have a WebService which sends a zip file to the browser. This works; when I test the WebService and 'invoke' the method through it directly, the zip file is downloaded to the browser correctly.

The problem arises when I use jQuery to send an AJAX request to the WebService - the zip file is downloaded to the response, but it stays in the response and doesn't download as a file.

Here is my code:

        HttpContext.Current.Response.ClearHeaders();
        HttpContext.Current.Response.ClearContent();
        HttpContext.Current.Response.ContentType = "application/zip";
        HttpContext.Current.Response.AddHeader("content-disposition", "attachment;         filename=pleasework.zip");


        using (ZipFile zip = new ZipFile())
        {
            zip.AddDirectory("c:\\inetpub\\mediaserver\\music\\mixes");
            zip.AddFile("c:\\test.txt");
            zip.AddFile("c:\\test2.txt");
            zip.Save("c:\\filename.zip");
        }
        HttpContext.Current.Response.TransmitFile("c:\\iloveshrooms.zip");
        return "done";        
}

Now this works since the file downloads when I use the 'invoke' function when navigating directly to the service.

Here is my jQuery AJAX request...

function getFile() {
            alert("sending POST request...");
            $.ajax({
                type:   'POST',
                url:    'ZipService.asmx/GetZipFile HTTP 1.1',
                contentType: "application/x-www-form-urlencoded",
                data:   '{ "path":"c:\\inetpub\\mediaserver\\music\\mixes"  }',
                dataType: '',
                beforeSend: function(xhr) {xhr.setRequestHeader("Accept","application/zip");},
                success: function() {alert(":-)");},
                failure: function() {alert(":-(");}
            });
        }

I added the code in 'beforeSend' so that the request states explicitly what type of response the browser should expect.

I've been using Firebug to monitor the request/response headers and can't see anything wrong with them (except when I look at the content of the response, it's full of binary data AND its the same size as the file I'm sending.

I just attempted to upload screen-dumps of the request/response headers and the content of the reponse but I don't have enough reputation points to do this yet :-(

The Response is the same size of the Zip file so I'm assuming its being sent back to the browser, but the browser doesn't know what to do with it.

Tested in IE, FF & Chrome and the results are consistent.

If anyone could shed any light on this I'd greatly appreciate it!

A: 

You can't receive a binary file over an ajax call like that... what is the browser to do with it?... Instead, return a link to the file and present that to the user (or navigate to it directly with window.location in your callback function).

So when you create that zip file, give it some unique name, store it in a temporary location accessible from the web, and send the link back.

Fosco
Finally discovered that an AJAX request can only return some form of text!
icecreamsoop
+1  A: 

There are a couple of easy solutions.

Convert your server procedure to use a GET request, you can use window.open, to initialize the download.

window.open('your_procedure_url?parameter=xyz')

If you want stick with POST, you can create a hidden form, with inputs for each of the parameters. Set the form action to POST to your service url and use form.submit() to launch the download.

mikerobi