API controllers and MVC controllers

1 min read

ASP.NET Core supports building both traditional Model-View-Controller (MVC) web applications and HTTP-based Web APIs.

MVC controllers

MVC controllers are designed mainly for web applications that render HTML views on the server. Their actions typically return ViewResult (to render a Razor view), or other IActionResult types that lead to an HTML response. They often use convention-based routing, but can also use attribute routing. See the routing noteRoutingHow an incoming URL finds the code that handles it.Opens in a new tab.

API controllers

API controllers are designed specifically for building Web APIs that expose data and functionality over HTTP. Their actions usually return data directly, which ASP.NET Core serializes to JSON or XML. Or they return IActionResult types like:

  • OkObjectResult, for a 200 OK with data
  • CreatedAtActionResult, for a 201 Created
  • NotFoundResult, for a 404
  • BadRequestObjectResult, for a 400

API controllers are typically decorated with the [ApiController] attributeAttributes and reflectionAttributes tag code with metadata, and reflection reads that metadata back at runtime.Opens in a new tab, and rely heavily on attribute routing, for example [Route("api/[controller]")].

The [ApiController] attribute

Applying [ApiController] to an API controller enables several opinionated, API-specific behaviors:

  • Automatic HTTP 400 responses. If model validation fails (based on validation attributes on the model), the framework automatically returns an HTTP 400 (Bad Request) response with details of the validation errors. You don’t need explicit ModelState.IsValid checks in the action method.
  • Attribute routing requirement. It enforces the use of attribute routing for actions in the controller.
  • Binding source inference. It gives more intuitive rules for inferring where action parameters are bound from, such as the request body, the route or the query string.

Using [ApiController] consistently for Web APIs leads to cleaner, more predictable, more conventional controller code.


Sources