Controller-based APIs
ApiController attribute
The [ApiController]
attribute can be applied to a controller class to enable the following opinionated, API-specific behaviors:
Attribute routing requirement
The [ApiController]
attribute makes attribute routing a requirement.
Actions are inaccessible via conventional routes defined by UseEndpoints
, UseMvc
, or UseMvcWithDefaultRoute
.
Automatic HTTP 400 responses
The [ApiController]
attribute makes model validation errors automatically trigger an HTTP 400 response.
Binding source parameter inference
A binding source attribute defines the location at which an action parameter's value is found.
[FromBody]
Request body
[FromForm]
Form data in the request body
[FromHeader]
Request header
[FromQuery]
Request query string parameter
[FromRoute]
Route data from the current request
[FromServices]
The request service injected as an action parameter
Multipart/form-data request inference
Problem details for error status codes
Action return types
Specific type
[HttpGet]
public List<Product> Get() =>
_repository.GetProducts();
[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts() {
var products = _repository.GetProducts();
foreach (var product in products) {
if (product.IsOnSale)
yield return product;
}
}
[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync() {
var products = _repository.GetProductsAsync();
await foreach (var product in products) {
if (product.IsOnSale)
yield return product;
}
}
IActionResult
type
Synchronous action
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById(int id) {
if (!_repository.TryGetProduct(id, out var product))
return NotFound();
return Ok(product);
}
Asynchronous action
[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateAsync(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return BadRequest();
}
await _repository.AddProductAsync(product);
return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}
ActionResult<T>
type
ActionResult<T>
return type enables you to return a type deriving from ActionResult
or return a specific type.
Synchronous action
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById(int id) {
if (!_repository.TryGetProduct(id, out var product))
return NotFound();
return product;
}
Asynchronous action
[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync(Product product) {
if (product.Description.Contains("XYZ Widget"))
return BadRequest();
await _repository.AddProductAsync(product);
return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}
[ProducesResponseType]
indicates the known types and HTTP status codes to be returned by the action. This attribute produces more descriptive response details from web API help pages generated by tools like Swagger.
Last updated
Was this helpful?