Microsoft Developer Network
API controllers are a fundamental part of building web APIs with ASP.NET Core. They handle incoming HTTP requests and formulate HTTP responses.
An API controller is a type of controller that is specifically designed to return data, typically in JSON or XML format, rather than HTML views. In ASP.NET Core, API controllers inherit from ControllerBase
(or Controller
if you need support for views and model validation, although this is less common for pure APIs).
[Route]
and [ApiController]
configure how requests are routed to controller actions.[HttpGet]
, [HttpPost]
, [HttpPut]
, [HttpDelete]
to indicate the HTTP method they handle.Let's create a basic API controller that returns a list of items.
ProductsController.cs
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using YourApp.Models; // Assuming you have a Product model
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly List<Product> _products = new List<Product>
{
new Product { Id = 1, Name = "Laptop", Price = 1200.00m },
new Product { Id = 2, Name = "Keyboard", Price = 75.50m },
new Product { Id = 3, Name = "Mouse", Price = 25.00m }
};
[HttpGet]
public ActionResult<IEnumerable<Product>> Get()
{
return Ok(_products);
}
[HttpGet("{id}", Name = "GetProductById")]
public ActionResult<Product> Get(int id)
{
var product = _products.Find(p => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
[HttpPost]
public ActionResult<Product> Post([FromBody] Product newProduct)
{
if (newProduct == null)
{
return BadRequest();
}
// Assign a new ID (in a real app, this would come from a database)
newProduct.Id = _products.Count > 0 ? _products.Max(p => p.Id) + 1 : 1;
_products.Add(newProduct);
return CreatedAtRoute("GetProductById", new { id = newProduct.Id }, newProduct);
}
}
// Assuming a simple Product model:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
[ApiController]
AttributeApplying the [ApiController]
attribute to a controller class enables several project-wide API behaviors:
[Route]
are inferred for action methods.400 Bad Request
if the model state is invalid.null
will return 204 No Content
.[FromBody]
, [FromQuery]
).multipart/form-data
.[Route]
The [Route]
attribute defines the base URL path for the controller's actions. Using the pattern "api/[controller]"
is a common convention:
api/
: A prefix for all API endpoints.[controller]
: A token that gets replaced by the controller's name (excluding the "Controller" suffix). For ProductsController
, this becomes products
.So, a request to /api/products
would target this controller.
Routes on action methods can further refine this, for example, [HttpGet("{id}")]
creates a route like /api/products/{id}
.
Action methods typically return types that derive from ActionResult
. This provides a way to return different HTTP status codes and response bodies. Common examples include:
Ok(object value)
: Returns an HTTP 200 OK response with the specified value.NotFound()
: Returns an HTTP 404 Not Found response.BadRequest(object error)
: Returns an HTTP 400 Bad Request response.Created(string uri, object value)
: Returns an HTTP 201 Created response, often with a Location
header pointing to the new resource.NoContent()
: Returns an HTTP 204 No Content response.ControllerBase
vs. Controller
For pure API projects, inheriting from ControllerBase
is recommended as it has fewer dependencies than Controller
, which includes MVC view support.
Always define clear API contracts. Use DTOs (Data Transfer Objects) to shape the data returned from your API and avoid exposing internal domain models directly.