Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am currently looking for a way to force a download of a file which is returned through a WebAPI controller.

I was using http://www.shawnmclean.com/blog/2012/04/force-download-of-file-from-asp-net-webapi/ as a reference.

On my client I am using an ajax GET call to send up an ID of an object and try to download the file

    exportList: (foo, callback) =>
        path = '/api/export/id'
        path = path.replace("id", foo.id)
        $.ajax(
            url: path,
            dataType: 'text',
            success: (data) =>
                callback(data)
            error: (data) =>
                callback(false)
        )

On the server-side, I have the above URI routed to the method below

    [AcceptVerbs("GET")]
    public HttpResponseMessage ExportList(int id)
    {
        string file = fooService.ExportList(id);

        if (file == null)
        {
            return Request.CreateResponse(HttpStatusCode.NoContent);
        }
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new StringContent(file);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        result.Content.Headers.ContentDisposition.FileName = "List.csv";

        return result;
    }

The fooService.ExportList method simply creates a csv string.

When watching the request come back to the client, the response does have the csv string in it, but the client is not prompted or forced to download it.

Is this the correct way to go about this?

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

I think your using javascript because of the dynamic id? If you can post directly with a form then use such solution. If javascript really is needed then use this piece of code to simulate a form action:

$.download = function (url, data, method) {
    if (url && data) {
        //data can be string of parameters or array/object
        data = typeof data == 'string' ? data : jQuery.param(data).replace("\+", " ");
        data = data.replace(/\+/g, " ");
        var inputs = '';
        jQuery.each(data.split('&'), function () {
            var pair = this.split('=');
            inputs += '<input type="hidden" name="' + pair[0] + '" value="' + pair[1] + '" />';
        });
        //send request
        jQuery('<form action="' + url + '" method="' + (method || 'post') + '">' + inputs + '</form>')
        .appendTo('body').submit().remove();
    };
};

The code to call the download (in stead of the ajax call):

path = '/api/export/id'
path = path.replace("id", foo.id)
$.download(path);
share|improve this answer
 
this looks like a nice solution, but when used as described, both the data and method parameters will be empty, and so it does not get past the If statement. Could you possibly expand on the $.download method a little? I can get it to work by calling as $.download(path, " ", "GET") –  Thewads Nov 7 '12 at 14:49
 
your right you should call the download with data. If no data available then you could pass {} as a parameter i guess. I hope this will help you (If not just ask)! –  PcPulsar Nov 8 '12 at 14:35
add comment

don't use ajax to request a download. do a full GET request. if you want, open the download in the new window.

<a href="..." target="_blank">download file</a>
share|improve this answer
 
I am using dynamic IDs, so I can not really hard-code an href. –  Thewads Nov 7 '12 at 14:44
2  
@Thewads What is stopping you from setting the href dynamically if you can make an AJAX call dynamically? –  Dismissile Nov 7 '12 at 15:01
 
@Dismissile I could update the hrefs, but this would be create more overheads than other solutions –  Thewads Nov 7 '12 at 15:11
 
"overhead". i doubt that. whatever you find to be the easiest to maintain and least likely to introduce side effects would be a good solution. –  Jason Meckley Nov 7 '12 at 15:21
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.