简体   繁体   中英

Confused with FromBody in ASP.NET Core

I have the following WEB API method, and have a SPA template with Angular:

[HttpPost]
public IActionResult Post([FromBody]MyViewModel model)

I thought, based on this topic, there is no need to use [FromBody] here, since I want to read the value from the message body, so there is no need to override the default behavior, but, if I don't use [FromBody] , the model that is coming from Angular is null. I'm really confused, why should I use [FromBody] , since I have used the default behavior?

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!

See my discussion https://stackoverflow.com/a/75263628/5555938 on [FromBody] . It explains everything in great detail!

But in summary, [FromBody] does NOT accept HTML Form field name-value pairs like [FromForm] . It does NOT accept a traditional HTML form submission: It requires the following:

  1. JavaScript POST Request manually sent to the Web API server
  2. JavaScript Http Header with JSON mime-type attached
  3. JavaScript Http Body with form field extracted data, reformatted and submitted as JSON. Traditional HTML POST name-value pairs will not work!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM