`[ApiController]` applies common web API conventions to an ASP.NET Core controller. It removes routine code for binding request data, handling invalid models, and describing errors. A typical web API controller also derives from `ControllerBase` and uses attributes such as `[HttpGet]` or `[HttpPost]` to define its endpoints. section 20.4 section 20.1
Updating a value
Put `[ApiController]` on a `ControllerBase` class with an `[HttpPost("fruit")]` action that accepts an `UpdateModel` parameter. If `UpdateModel.Name` has `[Required]`, an invalid request receives a 400 Bad Request response automatically; the action does not need its own `ModelState.IsValid` check. The attribute also infers that this complex parameter comes from the request body, so the action does not need `[FromBody]`. The action still decides whether an ID exists and can return `NotFound()` when it does not. section 20.4 section 20.7
The main conventions are:
- Infer a binding source for action parameters, including the request body for the complex model in the update example. section 20.4
- Return 400 Bad Request with validation details when model validation fails. section 20.4
- Use Problem Details for status-code errors, giving clients a consistent error format. section 20.1
Keep application decisions in the action: `[ApiController]` handles the repeated API conventions, not whether an update should succeed. If a convention does not fit an existing API specification, configure the behavior through `ConfigureApiBehaviorOptions()`; for example, `SuppressModelStateInvalidFilter` turns off the automatic invalid-model response. Without `[ApiController]`, an action filter can handle invalid model state, but that requires code the attribute normally supplies. section 20.4 section 22.1.3
Listing 20.11 Creating a web API controller with the [ApiController] attribute
[ApiController] #1 public class FruitController : ControllerBase { List<string> _fruit = new List<string> { "Pear", "Lemon", "Peach" }; [HttpPost("fruit")] public ActionResult Update(UpdateModel model) #2 { #3 if (model.Id < 0 || model.Id > _fruit.Count) { return NotFound(); #4 } _fruit[model.Id] = model.Name; return Ok(); } public class UpdateModel { public int Id { get; set; } [Required] public string Name { get; set; } } } #1 Adding the [ApiController] attribute applies several conventions common to API controllers. #2 The [FromBody] attribute is assumed for complex action method parameters. #3 The model validation is automatically checked, and if invalid, returns a 400 response. #4 Error status codes are automatically converted to a ProblemDetails object.
The update action shows the attribute, an inferred request-body model, a `[Required]` property, and an application-specific `NotFound()` decision together. section 20.4

