What is the difference between [FromBody], [FromForm], [FromQuery] and [FromRoute]?
Quick Answer
[FromRoute] — from the URL path template. [FromQuery] — from the query string. [FromBody] — deserialized from the request body (JSON); only one per action. [FromForm] — from multipart/form-data or url-encoded form fields, used for file uploads. With [ApiController], sources are inferred: complex types from body, simple types from route/query.
[FromRoute] pulls from the URL path, [FromQuery] from the query string, [FromBody] deserializes the JSON body, and [FromForm] reads form fields, which is what you use for file uploads with IFormFile. The key rules: only one [FromBody] per action because there's a single body stream, so if I need multiple things from the body I wrap them in one DTO. And with [ApiController] on I usually don't need the attributes at all — complex types are assumed to come from the body, simple ones from the route or query.
- You can't have two
[FromBody]parameters — the body is a single stream. Combine into one DTO. - File upload:
public IActionResult Upload([FromForm] IFormFile file, [FromForm] string category). [FromHeader]and[FromServices](DI) also exist.- Mixing
[FromBody]and[FromForm]in one action doesn't work — the content type is one or the other.