3

There is problem in sending ajax requests that have multiple parameters to asp.net mvc core 3 action using http post method. the parameters do not bind. In dot net framework asp.net web api there was similar limitation but not in asp.net mvc actions. I want to know is there work around this in asp.net core 3 mvc or is this the new limitation? action:

public string SomeAction([FromBody]string param1, [FromBody]IEnumerable<SomeType> param2, [FromBody]IEnumerable<SomeType> param3)
{
       //param1 and param2 and param3 are null
}

client:

    $.ajax({
        contentType: 'application/json',
        data: JSON.stringify({
            "param1": "someString",
            "param2": someList,
            "param3": someList
        }),
        type: "POST",
        dataType: "json",
        url: "/SomeController/SomeAction",
        success: function (result) {
        },
        error: function (error) {
            console.error(error);
        }
    }
    );
5
  • Are you getting any errors? Commented Oct 22, 2019 at 11:11
  • No. just getting null parameters Commented Oct 22, 2019 at 11:12
  • Can you wrap parameters with an object and try with [FromBody] attribute? Commented Oct 22, 2019 at 11:14
  • If possible put all parameter in one modelclass Commented Oct 22, 2019 at 11:15
  • @Ma core is a complete rewrite of the previous version. There are things that worked in mvc 5+ that have been refined in the new version. Commented Oct 22, 2019 at 11:18

3 Answers 3

2

With the new version actions need to be explicit about what and where they expected to bind models from.

Create a mode to hold all the required data

public class SomeActionModel {
    public string param1 { get; set; }
    public IEnumerable<SomeType> param2 { get; set; }
    public IEnumerable<SomeType> param3 { get; set; }
}

Update the action to expect the data from the body of the request

public IActionResult SomeAction([FromBody] SomeActionModel model) {
    if(ModelState.IsValid) {
        string param1 = model.param1;
        IEnumerable<SomeType> param2 = model.param2;
        IEnumerable<SomeType> param3 = model.param3;

        //...

        return Ok();
    }

    return BadRequest(ModelState);
}

The client should also send the data in the correct format

var model = {
    param1: GeometricNetworkTrace_Class.flags,
    param2: GeometricNetworkTrace_Class.barriers,
    param3: feederIds
};

$.ajax({
    contentType: 'application/json',
    data: JSON.stringify(model),
    type: "POST",
    dataType: "json",
    url: "/controllerName/actionName",
    success: function (result) {
    },
    error: function (error) {
        console.error(error);
    }
});

Reference Model Binding in ASP.NET Core

Sign up to request clarification or add additional context in comments.

1 Comment

Not with JSON. JSON is very literally "object notation", so you need to bind it to an object, not a bunch of different params. You can send via x-www-form-urlencoded, and bind that to multiple params, because it's just key-value pairs.
1

The reason for a single [FromBody] parameter is described in Parameter Binding in ASP.NET Web API. The request body might be stored in a non-buffered stream that can only be read once.

With a custom model binder you can get around it. See Posting JavaScript types to MVC 6 in .NET core, using Ajax.

Comments

-2

Try adding [FromBody] attribute in your controller signature.

public string SomeAction([FromBody] string param1, IEnumerable<SomeType> param2, IEnumerable<SomeType> param3)
{
       //param1 and param2 and param3 are null
}

2 Comments

FromBody attribute is used where we have complex object. And when we try to tell the mvc that the requested data is with in the body of the request. But here the parameters of the function you are specifying are just the simple types not the complex object
Even if it does not look like a complex object, the 2nd & 3rd params are IEnumerable<SomeType>. SomeType may or may not be a complex type, and Enumerable when used in querystring can see easily lead to [a huge querystring & some problems] (stackoverflow.com/a/48230425/12163640).

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.