Reputation: 5053
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?
Upvotes: 5
Views: 9904
Reputation: 444
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);
Upvotes: 3
Reputation: 7591
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>
Upvotes: 3