3

While porting an existing Web API 2 app to ASP.NET Core, I've noticed that now we're required to apply the FromBodyAttribute to an action method's parameter (POST request with json payload):

[HttpPost]
public IActionResult([FromBody]MyComplexType parameter){ ... }

I've tried searching the docs but haven't found anything that explains the rationale behind this decision. I did find a post that says that this was done in order to improve security (CSRF scenarios).

Can someone please give more info about this?

Thanks.

Luis

Luis Abreu
  • 4,008
  • 9
  • 34
  • 63
  • I remember thinking a similar thing when working with webapi 2. It's to do with the primitive/complex types. There's a post here: https://stackoverflow.com/questions/24625303/why-do-we-have-to-specify-frombody-and-fromuri and microsoft post on it here: https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api - hope that helps! – uv_man Jul 17 '18 at 13:30
  • Hello. I'm working with asp.net core. With web api 2, there was no need to add the FromBody to the complex parameter type... – Luis Abreu Jul 17 '18 at 13:54
  • Here's a [link](https://youtu.be/P9HqMZviaMg?t=2793) to Damian's explanation that Andrew Lock refers to. Are you using ASP.NET Core 2.1? – Kirk Larkin Jul 17 '18 at 13:56
  • Thanks Kirk. A little more detail, but still not enough...I mean, basically, it says the same thing as the post...I'd love to see some real examples of the csrf problems they've found while using the "old" binding approach... – Luis Abreu Jul 17 '18 at 14:02

1 Answers1

9

The default ComplexTypeModelBinder builds up a complex object graph from name value pairs that come from the request. Those name value pairs come from various IValueProvider implementations. That can represent, the query string, form values, headers, or a custom source. The default behavior for ASP.NET Core was based on the original ASP.NET MVC behavior where a complex object isn't just made up of data from the request body, but from the various parts of the request. This means that you could end up with values in your object from the query string as well as the body.

To make it explicit, we made a call in ASP.NET Core MVC to require [FromBody] to circumvent this behavior and call into the IInputFormatter pipeline directly.

PS: In ASP.NET Core 2.1 controllers decorated with the [ApiController] attribute get this for free without having to specify [FromBody] explicitly.

davidfowl
  • 37,120
  • 7
  • 93
  • 103
  • Thanks David! Btw, does the apicontroller mimics the web api2 behavior you mentioned at the beginning of your answer or will it only use data from the body? – Luis Abreu Jul 17 '18 at 22:45
  • Yes, it will assume that complex types are automagically [FromBody]. If you're interested, here's where that is implemented https://github.com/aspnet/Mvc/blob/a67d9363e22be8ef63a1a62539991e1da3a6e30e/src/Microsoft.AspNetCore.Mvc.Core/Internal/ApiBehaviorApplicationModelProvider.cs#L238 – davidfowl Jul 18 '18 at 06:04