1
votes

Working in MVC/ASP.NET, I want to call action methods of a Web API controller (this controller is called "TreinreisController") from my view. For that purpose, I have the following javascript/jQuery function in the view:

function sendAjaxRequest(httpMethod, controller, callback, url, reqData) {
         $.ajax("/api/" + controller + (url ? "/" + url : ""), {
               type: httpMethod,
               contentType: "application/json",
               dataType: "json",
               traditional: true,
               data: JSON.stringify(reqData),
               success: callback,
               error: function (x, y, z) {
                   var err = eval("(" + x.responseText + ")");
                   alert(err.Message);
               },
               data: reqData
         });
}

I call this function whenever I want to make an ajax call to a controller action method using JSON. And this works perfectly if I only place a string (param1) in the data object, like this:

        var param1 = "some_string";
        sendAjaxRequest("POST", "treinreis", function (data) {
                           alert("Succes!");
                        },
        "action_method_name",
        {param1: param1}
        );

But it goes wrong when I add an array of integers as a second parameter (param2), like this:

        var param1 = "some_string";
        var param2 = [8, 17];
        sendAjaxRequest("POST", "treinreis", function (data) {
                               alert("Succes!");
                            },
        "action_method_name",
        {param1: param1, param2: param2}
        );

In the case of 2 parameters, with one being an array, the action method is never reached. Unfortunately, the error message I get from the alert in the error callback-function in function sendAjaxRequest only says: "An error has occurred", which is less than helpful.

I've checked that the array arrives intact in function sendAjaxRequest, and that's in fact the case. So the problem seems to have to do with the JSON serialization, or maybe routing (although the latter seems strange, because the same routing works perfectly with only param1).

The action method in the controller, TreinreisController, goes like this (I'm showing the version with both parameters; the one that only takes param1 should of course be modified accordingly):

[System.Web.Http.HttpPost]   
[System.Web.Http.Route("api/treinreis/action_method_name")]
public void MyActionMethod([FromBody] string param1, 
                           [FromBody] int[] param2) {
    // do calculations, whatever
}

I note that the parameters in the action method have the same names as the ones used in the data-object in the view (i.e., param1 and param2).

What am I doing wrong. Why does work with only param1, but not when I add param2?

Many thanks, and I'll be able to check back in a few hours.

1
You are passing Json to controller action you need to pass $('form').serialize(); instead of JSON.stringify(reqData) - Laxman Gite
Use your browser tools (the Network tab) to inspect the response which will give you the details of the error. - user3559349
Note also you cannot use [FromBody] twice. Refer Parameter Binding in ASP.NET Web API - user3559349
Instead, create a model that contains int param1 and int[] param2 - user3559349
data: $('form').serializeArray(), - REDEVI_

1 Answers

1
votes

You cannot do this! It is by design that at most one parameter is allowed to read from the message body. Hence, this will not work.

The reason for this rule is that the request body might be stored in a non-buffered stream that can only be read once.

https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

There a few workarounds that you can use to make this work:

  1. Use both POST and QueryString Parameters in Conjunction
  2. Use a single Object that wraps the two Parameters
  3. Use JObject to parse multiple Property Values out of an Object

https://weblog.west-wind.com/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods