Leandro Bremer
Leandro Bremer

Reputation: 11

.Net Core API - Mixed Model Binding not working

Framework used is .Net Core 3.0 but tested in 2.2 and got the same behavior.

I am using a class to automatically bind the body request properties and that works pretty well, even without having the [FromBody] attribute on them.

Now, I added a new property in this class that will match a property from the header and it works if I use it directly into the controller, like this:

public IActionResult Test(TestRequest request, [FromHeader(Name = "Authorization")] string token)

However, when I try to get the same result by adding the [FromHeader] attribute into the class property, it doesn't work.

Here is a sample code to illustrate the issue:

[ApiController]
[Route("api")]
public class TestController : ControllerBase
{
    [HttpPost]
    [Route("Test")]
    public IActionResult Test(TestRequest request)
    {
        Console.WriteLine("request.UserId: " + request.UserId);
        Console.WriteLine("request.Token: " + request.Token);
        return Ok();
    }
}
public class TestRequest
{
    [FromBody]
    public string UserId { get; set; }

    [FromHeader(Name = "Authorization")]
    public string Token { get; set; }
}

Did anybody ever face the same issue?

Upvotes: 1

Views: 3328

Answers (1)

Ryan
Ryan

Reputation: 20116

You need to configure SuppressInferBindingSourcesForParameters as true in ConfigureServices in Startup.cs like below :

services.AddMvc().ConfigureApiBehaviorOptions(options =>
        {
            options.SuppressInferBindingSourcesForParameters = true;
        });

Action:

[HttpPost]
[Route("Test")]
public IActionResult Test(TestRequest request)

And call the api with your Authorization header(not shown below) and body string, for postman enter image description here

Update:

Since you use [FromBody] on the string property,it accepts a string instead of json object.

If you still would like to pass json object as { "userId" : "123" }, you could warp the userId into a model,for example:

public class User
{
    public string UserId { get; set; }
}
public class TestRequest
{
    [FromBody]
    public User User { get; set; }

    [FromHeader(Name = "Authorization")]
    public string Token { get; set; }
}

Upvotes: 5

Related Questions