Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused with FromBody in ASP.NET Core

People also ask

What is difference between FromQuery and FromBody?

[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.

Can we declare FromBody attribute on multiple parameters?

The [FromBody] attribute can be applied on only one primitive parameter of an action method. It cannot be applied to multiple primitive parameters of the same action method.

Can we use FromBody with Httpget?

Please note that we are able to send [FromBody] parameter in HTTP GET Request input.

What is FromBody ASP NET core?

In order to bind the JSON correctly in ASP.NET Core, you must modify your action to include the attribute [FromBody] on the parameter. This tells the framework to use the content-type header of the request to decide which of the configured IInputFormatters to use for model binding.


For anyone seeing this issue .net core 3 - you need to add the [ApiController] to the controller where you extend ControllerBase. The [FromBody] is only needed if you're doing an MVC controller.

This causes the body to get automatically processed in the way you're expecting.

Microsoft documentation for the ApiController attribute


The question you linked to is referring to web-api. You are using core-mvc which has been re-written to merge the pipelines for the previous mvc and web-api versions into one Controller class.

When posting json (as apposed to x-www-form-urlencoded), the [FromBody] attribute is required to instruct the ModelBinder to use the content-type header to determine the IInputFormatter to use for reading the request.

For a detailed explanation of model binding to json in core-mvc, refer Model binding JSON POSTs in ASP.NET Core.


And here's an alternate approach assuming you need to support both [FromForm] and [FromBody] in your Controller API…

Front-End (Angular Code):

forgotPassword(forgotPassword: ForgotPassword): Observable<number> {
  const params = new URLSearchParams();
  Object.keys(forgotPassword).forEach(key => params.append(key, forgotPassword[key]));
  return this.httpClient.post(`${this.apiAuthUrl}/account/forgotpassword`, params.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
}

Back-End (C# Code):

[AllowAnonymous]
[HttpPost("[action]")]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model) { }

Now your signature can remain the same so it can support both.

And another more permanent approach I thought about while addressing.

https://benfoster.io/blog/aspnet-core-customising-model-binding-conventions.

Hope it helps someone!