Only one parameter per action may be bound from body in ASP.NET Core

By FoxLearn 3/7/2025 4:41:15 AM   101
When working with web APIs in ASP.NET Core, you might encounter an error when multiple parameters in your action method are bound to the request body.

The error appears as:

System.InvalidOperationException: Action ‘MyController.Post’ has more than one parameter that was specified or inferred as bound from request body. Only one parameter per action may be bound from body.

This results in the immediate crash of the web API host process, meaning you won’t receive a standard error response. Instead, you might get a “connection refused” or similar error message because the web API is not running.

The two primary scenarios where you might face this issue are:

  1. You have multiple complex type parameters.
  2. You use the [FromBody] attribute on multiple parameters.

Below, I'll illustrate each scenario with examples and solutions.

Case 1: Multiple Complex Type Parameters

By default, the ASP.NET Core framework binds complex types (like model classes) to the request body. If you have more than one complex type parameter, the framework will not know which one to bind, causing the error.

[HttpPost()]
public IActionResult Post(Product product, Order order)
{
    return Ok();
}

In this example, both Product and Order are complex types, so they will be bound to the request body, leading to an error.

Solution: If both parameters are part of the request body, you should combine them into a single model class to represent the entire request body. This way, ASP.NET Core will only bind that single model to the body.

public class RequestModel
{
    public Product Product { get; set; }
    public Order Order { get; set; }
}

[HttpPost()]
public IActionResult Post(RequestModel requestModel)
{
    return Ok($"Product name={requestModel.Product.Name} Order ID={requestModel.Order.Id}");
}

The request body would look like:

{
  "product": {
    "name": "Laptop",
    "price": 1200
  },
  "order": {
    "id": 1234,
    "date": "2025-03-07"
  }
}

Now, the framework can map both Product and Order inside the RequestModel object, resulting in a successful request.

Case 2: Multiple [FromBody] Attributes

Another issue arises when you attempt to use the [FromBody] attribute on multiple parameters in the same action. ASP.NET Core does not allow this, and you'll get the same fatal exception.

[HttpPost()]
public IActionResult Post([FromBody] string name, [FromBody] int quantity)
{
    return Ok();
}

In this example, both name and quantity are primitive types and marked with [FromBody], which leads to the error.

Solution: To fix this, create a model class that groups the parameters together:

public class OrderRequest
{
    public string Name { get; set; }
    public int Quantity { get; set; }
}

[HttpPost()]
public IActionResult Post(OrderRequest orderRequest)
{
    return Ok($"Ordered {orderRequest.Quantity} of {orderRequest.Name}");
}

Now, send a request with the body like:

{
  "name": "Phone",
  "quantity": 2
}

ASP.NET Core will correctly bind the data to the OrderRequest object, and the action will return a successful response.

In ASP.NET Core, only one parameter in an action method can be bound to the request body.

To resolve the issue:

  • If you have multiple complex types in the body, group them into a single model class.
  • Avoid using multiple [FromBody] attributes on different parameters.

By following these guidelines, you can ensure that your web API actions correctly handle request data without causing errors.