14

I am new to using ASP.NET MVC 4 with Web Api.

I want to allow user to download a file, this file I will be creating on the server side. For creating the file I have managed to get hold of the following code

[ActionName("Export")]
public HttpResponseMessage PostExportData(SomeModel model)
{           
    string csv = _service.GetData(model);
    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    result.Content = new StringContent(csv);
    //a text file is actually an octet-stream (pdf, etc)
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    //we used attachment to force download
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
    result.Content.Headers.ContentDisposition.FileName = "file.csv";
    return result;            
}

HOW TO CALL THIS WEB API METHOD USING JQUERY ?

But I am not sure of how to call this web api using jquery and make it return me a file, with a "save as / open" option that you normally get when downloading any file.

Can some one please help me and guide me in how to make the call and download the file. Thanks.

Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281

1 Answers1

9

You can do something like this inside the view where you want to use jquery. I assume the name of the controller is ExportController. You also have to break down the model variables, or alternatively collect the model inside HttpResponseMessage PostExportData(SomeModel model) via some other way.

html:

<a class="export">export</a>

javascript:

<script>
$('a.export').click(function(e) {
    e.preventDefault();  //stop the browser from following
    window.location.href = '@Url.Action('Export', 'ExportController', new { property = model.property, property = model.property2 })';
});
</script>

To use POST

function UpdateForm(modelObject) {
   if ($('#hidden-form').length < 1)
   {
       $('<form>').attr({
           method: 'POST',
           id: 'hidden-form',
           action: '@Url.Action('Export', 'Export')'
       }).appendTo('body');
   }
   $('#hidden-form').html('');
   for(var propertyName in modelObject) {
       $('<input>').attr({
            type: 'hidden',
            id: propertyName,
            name: propertyName,
            value: modelObject[propertyName]
       }).appendTo('#hidden-form');
    }
}

$('a.export').click(function(e) {
    e.preventDefault();
    var modelObject = { property1 : "property1" };
    UpdateForm(modelObject);
    $('#hidden-form').submit();
});

Then you can just post #hidden-form via js which will trigger the file download

Update: This is a full example for posting, and its not checked for typos etc so debug any minor errors.

Mihalis Bagos
  • 2,500
  • 1
  • 22
  • 32
  • 1
    You have to drop the `Controller` part from the name, and also drop the ` new { property = model.property, property = model.property2 }` as its not working, its an example of how you should add variables there – Mihalis Bagos Oct 19 '12 at 14:46
  • If you *have* you use post you can do it via http://api.jquery.com/jQuery.post/ . You should drop the `new { property = model.property, property = model.property2 }` part again, and only use the base url generated by the helper. You will also have to somehow create a javascript object that will be posted with the request. I don't know your app so I can't help more than that, it really depends on you html and the data it holds. By the way, a get request (the example I gave) works because querystring variables are parsed properly too. – Mihalis Bagos Oct 19 '12 at 17:26
  • The number of parameters doesn't indicate the verb of the request. Just look at facebook's API, and the query strings you have to generate. I will update with a post method too though – Mihalis Bagos Oct 19 '12 at 17:42
  • What do you mean the action is not called? This is a function in javascript that you have to call, like `UpdateForm(modelObject);` AFTER you have created `modelObject`. Then you can submit the form using jquery: http://api.jquery.com/submit/ . I am going to write an example for the usage but you really have to look into this yourself, this is like doing your job for you – Mihalis Bagos Oct 20 '12 at 15:21
  • Try the last example. It will post the form to your action, and trigger the download of the file, which is what you want. You have to provide the parameters to `var modelObject = { property1 : "property1" };` in order to post the model correctly. If you provide definition of `SomeModel` I can give you a working example for that too – Mihalis Bagos Oct 21 '12 at 12:43
  • I take back all that I had said :) This works ! Thanks a ton. – Yasser Shaikh Oct 21 '12 at 15:58