Pass JavaScript / JSON array to MVC 'GET' method

I am trying to pass an array / IEnumerable from Guids to the MVC 'GET' method, which looks like this:

[HttpGet] public ActionResult ZipResults(IEnumerable<Guid> ids) { using(var zip = new Zip()) { foreach(var id in ids) { var stream = GetDataStream(id); zip.AddEntry("filename.txt", stream); } } var outputStream = new MemoryStream(); zip.Save(outputStream); return FileStreamResult(outputStream, "application/octet-stream"){ FileDownloadName = "Results.zip" }; } 

And my javascript looks like this:

 $('the-button').click(function(){ // 1. Get the guids from a table and add to javascript array (works fine) // 2. Grey-out screen and show processing indicator (works fine) // 3. This is how I'm calling the "ZipResults" action: $.ajax({ url: '@Url.Action("ZipResults", "TheController")', type: 'GET', data: $.toJSON({ ids: _ids }), dataType: 'json', contentType: 'application/json;charset=utf-8', traditional: true, success: function(){ // Undo the grey-out, and remove processing indicator }, error: function(){ } }); }); 

I expect this to open the download dialog in the browser. Be that as it may, the javascript array passed to the controller is null (on the server side it works correctly on the client side). Also, this works fine with "POST", however the "POST" method used will not force the download dialog ...

Open for suggestions :)

+4
source share
2 answers

You should avoid sending JSON requests using GET. Try it like this:

 var _ids = [ 'e2845bd4-9b3c-4342-bdd5-caa992450cb9', '566ddb9d-4337-4ed7-b1b3-51ff227ca96c', '25bc7095-a12b-4b30-aabe-1ee0ac199594' ]; $.ajax({ url: '@Url.Action("ZipResults", "TheController")', type: 'GET', data: { ids: _ids }, dataType: 'json', traditional: true, success: function() { // Undo the grey-out, and remove processing indicator }, error: function() { } }); 

In doing so, I see that you are invoking some kind of controller action that returns the uploaded file. You should not use AJAX for this. The reason for this is that in your callback you will get the contents of the ZIP file, but you cannot handle it. You cannot save it to the client computer, you cannot offer the user to choose a save location, you are pretty much ruined.

Thus, no AJAX calls if you want to upload a file. You can use a simple anchor:

 @Html.ActionLink("download zip", "ZipResults", "TheController", null, new { id = "download" }) 

and then:

 $(function() { $('#download').click(function() { var _ids = [ 'e2845bd4-9b3c-4342-bdd5-caa992450cb9', '566ddb9d-4337-4ed7-b1b3-51ff227ca96c', '25bc7095-a12b-4b30-aabe-1ee0ac199594' ]; var url = this.href; for (var i = 0; i < _ids.length; i++) { if (url.indexOf('?') > 0) { url += '&ids=' + encodeURIComponent(_ids[i]); } else { url += '?ids=' + encodeURIComponent(_ids[i]); } } window.location.href = url; return false; }); }); 
+4
source

The problem is that GET does not receive the request body. I suspect that if you look at the request requested by the client, you will find that it is trying to drag an enumerated query string ...

Post -> Redirect looks like the best action here.

+2
source

Source: https://habr.com/ru/post/1394399/


All Articles