2

I have a JavaScript function where I pass 4 arrays, each of these is of the type [1, 2] with only int values inside or [] with no values inside. these are passed into an Url.Action command.

function Filter(locations, machines, severities, messages) {
    var url = '@Url.Action("Filter", "ActiveMessages")?' + $.param({ 
        locations: locations, machines: machines, severities: severities, messages: messages });
    $.ajax({
        url: url,
        method: 'POST',
        traditional: true,
        success: function (data) { }
    });
}

I tried to build the parameters using $.param(). but this doesn't generate the parameters i'm expecting, I get something like this: "/ActiveMessages/Filter?locations%5B%5D=1"

I also tried doing this:

decodeURIComponent($.param({ locations: filterlocations, machines: filtermachines, severities: filterseverities, messages: filtermessages }))

Then I get something like this: "/ActiveMessages/Filter?locations[]=1&locations[]=2"

Are there any other ways to parse such an array into an url?

Receiving happens in the controller:

public async Task<ActionResult> Filter(int[] locations, int[] machines, int[] severities, int[] messages)
{
    //TODO filter
}

This gets called but the parameters are null;

when I started out I used this which works for a single value but needs to be extended to an array.

var url = '@Url.Action("Filter", "ActiveMessages")' + '?locations=' + locations + '&machines=' + machines + '&severities=' + severities + '&messages=' + messages;
5
  • Why do you want to pass them by URL? Commented Feb 23, 2017 at 13:58
  • what other way would you recommend? i thought it would be the easiest way since the data isn't private Commented Feb 23, 2017 at 13:59
  • 2
    I suggest to pass them with an AJAX POST and include all arrays on data property. Something like this stackoverflow.com/a/5489534/6157222 Commented Feb 23, 2017 at 14:02
  • Yes. Just use POST. You should pretty much always use POST with an AJAX call involving data. Commented Feb 23, 2017 at 14:26
  • 1
    If you did want to do this as a query string, then you need to use $.param({ ..... }, true); - your missing the 2nd parameter - refer documentation (and the traditional: true option would be pointless since you not sending any data in the body Commented Feb 23, 2017 at 21:48

3 Answers 3

2

best practise for a post action will be to use the body to send parameters for post (Note the [FromBody] annotation of paramters):

[HttpPost]
public async Task<ActionResult> Filter([FromBody] int[] locations, [FromBody] int[] machines, [FromBody] int[] severities, [FromBody] int[] messages)

the parameters needs to be specified in the body of the ajax call:

function Filter(locations, machines, severities, messages) {
     var url = '@Url.Action("Filter", "ActiveMessages")';
     $.ajax({
          url: url,
          method: 'POST',
          data: JSON.stringify({ locations: locations, machines: machines, severities: severities, messages: messages }),
          traditional: true,
          success: function (data) {
     }});
 }
Sign up to request clarification or add additional context in comments.

3 Comments

[FromBody] is unnecessary here. The method only allows POST, so the data will of course come from the post body.
I've implemented this but i'm still getting null as value in my controller
I've build the data like this : data: { 'locations': locations, 'machines': machines, 'severities': severities, 'messages': messages } as suggested by – Ivan Franco . Now i'm getting the data in my controller
2
var locations = [1,2];
var machines = [3,4];
var severities = [5,6];
var messages = [7,8];

$.ajax({
     url: @Url.Action("Filter", "ActiveMessages"),
     method: 'POST',
     data: { 
            locations: locations, 
            machines: machines, 
            severities: severities, 
            messages: messages 
     },
     success: function (data) {
     }
});

In this case, no need to stringify :)

Comments

2

While what the others say is totally true (body is made for that) sometimes it's still good to have a choice. The Problem with your query was that the keyword machines= (or locations etc.) must be repeated for each array value. Something like this would work:

const machines = [1, 2];
const locations = [3, 4];

function formatParamArray(array, name) {
  return `${name}=` + array.reduce((acc, cur) => `${acc}&${name}=${cur}`);
}

var url = '@Url.Action("Filter", "ActiveMessages")?'+formatParamArray(machines, 'machines')+'&'+formatParamArray(locations, 'locations');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.