25/11/24, 11:18 p.m. Creación de API web con ASP.
NET Core | Microsoft Learn
Creación de API web con
[Link] Core
Artículo • 06/11/2024
[Link] Core admite la creación de API web mediante controladores o
mediante API mínimas. Los controladores de una API web son clases
que se derivan de ControllerBase. Los controladores se activan y
eliminan por solicitud.
En este artículo se muestra cómo usar controladores para gestionar las
solicitudes de API web. Para obtener información sobre cómo crear API
web sin controladores, consulte Tutorial: Creación de una API mínima
con [Link] Core.
Clase ControllerBase
Una API web basada en controlador consta de una o varias clases de
controlador que se derivan de ControllerBase. La plantilla de proyecto
de API web proporciona un controlador de inicio:
C#
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Normalmente, los controladores de API web deben derivarse de
ControllerBase, en lugar de Controller. Controller se deriva de
ControllerBase y agrega compatibilidad con vistas, por lo que sirve
para gestionar páginas web, no solicitudes de API web. Si el mismo
controlador debe admitir vistas y API web, debe derivarse de
Controller .
[Link] 1/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
La clase ControllerBase ofrece muchas propiedades y métodos que
son útiles para gestionar solicitudes HTTP. Por ejemplo,
CreatedAtAction devuelve un código de estado 201:
C#
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
[Link] = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => [Link]) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id =
[Link] }, pet);
}
En la tabla siguiente se incluyen ejemplos de métodos en
ControllerBase .
ノ Expandir tabla
Método Notas
BadRequest Devuelve el código de estado 400.
NotFound Devuelve el código de estado 404.
PhysicalFile Devuelve un archivo.
TryUpdateModelAsync Invoca el enlace de modelo.
TryValidateModel Invoca la validación de modelos.
Para ver una lista de todos los métodos y propiedades disponibles,
consulte ControllerBase.
[Link] 2/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
Atributos
El espacio de nombres [Link] proporciona
atributos que se pueden usar para configurar el comportamiento de
los controladores API web y los métodos de acción. En el ejemplo
siguiente se usan atributos para especificar el verbo de acción HTTP
admitido y cualquier código de estado HTTP conocido que se pueda
devolver:
C#
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
[Link] = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => [Link]) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id =
[Link] }, pet);
}
Estos son algunos ejemplos más de atributos que están disponibles.
ノ Expandir tabla
Atributo Notas
[Route] Especifica el patrón de dirección URL de un controlador o una
acción.
[Bind] Especifica el prefijo y las propiedades que se incluirán en el
enlace de modelo.
[HttpGet] Identifica una acción que admite el verbo de acción GET HTTP.
[Consumes] Especifica los tipos de datos que acepta una acción.
[Link] 3/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
Atributo Notas
[Produces] Especifica los tipos de datos que devuelve una acción.
Para ver una lista que incluye los atributos disponibles, consulte el
espacio de nombres [Link].
Atributo ApiController
El atributo [ApiController] se puede aplicar a una clase de controlador
para permitir los siguientes comportamientos específicos de la API:
Requisito de enrutamiento mediante atributos
Respuestas HTTP 400 automáticas
Inferencia de parámetro de origen de enlace
Inferencia de solicitud de varios elementos o datos de formulario
Detalles de problemas de los códigos de estado de error
Atributo en controladores específicos
El atributo [ApiController] puede aplicarse a controladores
específicos, como se muestra en el siguiente ejemplo de la plantilla de
proyecto:
C#
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Atributo en varios controladores
Una estrategia para el uso del atributo en más de un controlador
consiste en crear una clase personalizada de controlador base anotada
[Link] 4/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
con el atributo [ApiController]. En el siguiente ejemplo se muestra una
clase base personalizada y un controlador que se deriva de ella:
C#
[ApiController]
public class MyControllerBase : ControllerBase
{
}
C#
[Produces([Link])]
[Route("[controller]")]
public class PetsController : MyControllerBase
Atributo en un ensamblado
El atributo [ApiController] puede aplicarse a un ensamblado. Cuando
el atributo [ApiController] se aplica a un ensamblado, todos los
controladores del ensamblado tienen aplicado el atributo
[ApiController] . No hay ninguna manera de excluir controladores
específicos. Aplique el atributo de nivel de ensamblado al archivo
[Link] :
C#
using [Link];
[assembly: ApiController]
var builder = [Link](args);
[Link]();
var app = [Link]();
[Link]();
[Link]();
[Link] 5/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[Link]();
[Link]();
Requisito de enrutamiento mediante
atributos
El atributo [ApiController] convierte el enrutamiento de atributos en
un requisito. Por ejemplo:
C#
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
No es posible acceder a las acciones mediante rutas convencionales
que hayan definido UseEndpoints , UseMvc o UseMvcWithDefaultRoute.
Respuestas HTTP 400 automáticas
El atributo [ApiController] hace que los errores de validación de un
modelo desencadenen automáticamente una respuesta HTTP 400. Por
lo tanto, el siguiente código no es necesario en un método de acción:
C#
if (![Link])
{
return BadRequest(ModelState);
}
[Link] Core MVC usa el filtro de acciones ModelStateInvalidFilter
para realizar la comprobación anterior.
[Link] 6/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
Respuesta BadRequest predeterminada
El tipo de respuesta predeterminado para una respuesta HTTP 400 es
ValidationProblemDetails. El siguiente cuerpo de respuesta es un
ejemplo del tipo serializado:
JSON
{
"type": "[Link]
6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|7fb5e16a-4c8f23bbfc974667.",
"errors": {
"": [
"A non-empty request body is required."
]
}
}
Tipo ValidationProblemDetails :
Proporciona un formato de lectura mecánica para especificar
errores en las respuestas de la API web.
Cumple los requisitos de la especificación RFC 7807 .
Para que las respuestas automáticas y personalizadas sean coherentes,
llame al método ValidationProblem en lugar de a BadRequest.
ValidationProblem devuelve un objeto ValidationProblemDetails y la
respuesta automática.
Registro de respuestas 400 automáticas
Para registrar respuestas 400 automáticas, establezca la propiedad
delegada InvalidModelStateResponseFactory para realizar el
procesamiento personalizado. De forma predeterminada,
[Link] 7/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
InvalidModelStateResponseFactory utiliza ProblemDetailsFactory para
crear una instancia de ValidationProblemDetails.
En el ejemplo siguiente se muestra cómo recuperar una instancia de
ILogger<TCategoryName> para registrar información sobre una
respuesta 400 automática:
C#
var builder = [Link](args);
[Link]()
.ConfigureApiBehaviorOptions(options =>
{
// To preserve the default behavior, capture the ori‐
ginal delegate to call later.
var builtInFactory =
[Link];
[Link] = context
=>
{
var logger = [Link]
.GetRequiredService<ILogger<Program>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a
ValidationProblemDetails
// response.
// To produce a custom response, return a diffe‐
rent implementation of
// IActionResult instead.
return builtInFactory(context);
};
});
var app = [Link]();
[Link]();
[Link] 8/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[Link]();
[Link]();
[Link]();
Deshabilitación de las respuestas 400
automáticas
Para deshabilitar el comportamiento 400 automático, establezca la
propiedad SuppressModelStateInvalidFilter en true . Agregue el código
resaltado siguiente:
C#
using [Link];
var builder = [Link](args);
[Link]()
.ConfigureApiBehaviorOptions(options =>
{
[Link] =
true;
[Link] =
true;
[Link] = true;
[Link] = true;
[Link][StatusCodes.Status404NotFound].Li
nk =
"[Link]
});
var app = [Link]();
[Link]();
[Link]();
[Link] 9/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[Link]();
[Link]();
Inferencia de parámetro de origen de
enlace
Un atributo de origen de enlace define la ubicación del valor del
parámetro de una acción. Existen los atributos de origen de enlace
siguientes:
ノ Expandir tabla
Atributo Origen de enlace
[FromBody] Cuerpo de la solicitud
[FromForm] Datos del formulario en el cuerpo de la solicitud
[FromHeader] Encabezado de la solicitud
[FromQuery] Parámetro de la cadena de consulta de la solicitud
[FromRoute] Datos de ruta de la solicitud actual
[FromServices] Servicio de solicitud insertado como parámetro de acción
[AsParameters] Parámetros de métodos
2 Advertencia
No use [FromRoute] si los valores pueden contener %2f (es decir,
/ ). %2f no incluirá el carácter sin escape / . Use [FromQuery] si el
valor puede contener %2f .
[Link] 10/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
Sin el atributo [ApiController] o los atributos de origen de enlace,
como [FromQuery] , el entorno de tiempo de ejecución de
[Link] Core intenta usar el enlazador de modelos de objetos
complejos. El enlazador de modelos de objetos complejos extrae los
datos de los proveedores de valor en un orden definido.
En el ejemplo siguiente, el atributo [FromQuery] indica que el valor del
parámetro discontinuedOnly se proporciona en la cadena de consulta
de la dirección URL de la solicitud:
C#
[HttpGet]
public ActionResult<List<Product>> Get(
[FromQuery] bool discontinuedOnly = false)
{
List<Product> products = null;
if (discontinuedOnly)
{
products = _productsInMemoryStore.Where(p =>
[Link]).ToList();
}
else
{
products = _productsInMemoryStore;
}
return products;
}
El atributo [ApiController] aplica reglas de inferencia a los orígenes
de datos predeterminados de los parámetros de acción. Estas reglas
aplican atributos a los parámetros de acción, lo que ahorra la
necesidad de identificar los orígenes de enlace manualmente. Las
reglas de inferencia de orígenes de enlace se comportan de la manera
siguiente:
[Link] 11/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[FromServices] se infiere para parámetros de tipo complejos
registrados en el contenedor de inserción de dependencias.
[FromBody] se infiere para parámetros de tipo complejos no
registrados en el contenedor de inserción de dependencias. La
excepción a [FromBody] esta regla es cualquier tipo integrado
complejo que tenga un significado especial, como
IFormCollection y CancellationToken. El código de inferencia del
origen de enlace omite esos tipos especiales.
[FromForm] se infiere para los parámetros de acción de tipo
IFormFile y IFormFileCollection. No se infiere para los tipos
simples o definidos por el usuario.
[FromRoute] se infiere para cualquier nombre de parámetro de
acción que coincida con un parámetro de la plantilla de ruta. Si
varias rutas coinciden con un parámetro de acción, cualquier
valor de ruta se considera [FromRoute] .
[FromQuery] se infiere para cualquier otro parámetro de acción.
Notas de la inferencia de FromBody
En el caso de los tipos simples, como string y int , [FromBody] no se
infiere. Así pues, para los tipos simples, en los casos en los que quiera
utilizar dicha funcionalidad, conviene usar el atributo [FromBody] .
Cuando una acción tiene más de un parámetro enlazado desde el
cuerpo de solicitud, se produce una excepción. Por ejemplo, todas las
firmas de acción siguientes provocan una excepción:
[FromBody] se infiere en ambos porque son tipos complejos.
C#
[HttpPost]
public IActionResult Action1(Product product, Order
order)
[Link] 12/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
El atributo [FromBody] en uno se infiere en el otro porque es un
tipo complejo.
C#
[HttpPost]
public IActionResult Action2(Product product, [From‐
Body] Order order)
El atributo [FromBody] se infiere en ambos.
C#
[HttpPost]
public IActionResult Action3([FromBody] Product pro‐
duct, [FromBody] Order order)
Notas de inferencia de FromServices
El enlace de parámetros enlaza parámetros mediante la inserción de
dependencias cuando el tipo está configurado como servicio. Esto
significa que no es necesario aplicar explícitamente el atributo
[FromServices] a un parámetro. En el código siguiente, ambas acciones
devuelven la hora:
C#
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
public ActionResult GetWithAttribute([FromServices] IDa‐
teTime dateTime)
=>
Ok([Link]);
[Route("noAttribute")]
public ActionResult Get(IDateTime dateTime) =>
[Link] 13/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
Ok([Link]);
}
En casos aislados, la inserción automática de dependencias puede
interrumpir las aplicaciones que tienen un tipo en la DI que también se
acepta en los métodos de las acciones del controlador de API. No es
habitual tener un tipo en la DI y como argumento en una acción del
controlador de API.
Para deshabilitar la inferencia de [FromServices] para un único
parámetro de acción, aplique el atributo de origen de enlace deseado
al parámetro. Por ejemplo, aplique el atributo [FromBody] a un
parámetro de acción que se debe enlazar desde el cuerpo de la
solicitud.
Para deshabilitar la inferencia [FromServices] globalmente, establezca
DisableImplicitFromServicesParameters en true :
C#
using [Link];
var builder = [Link](args);
[Link]();
[Link]<IDateTime, SystemDateTime>();
[Link]<ApiBehaviorOptions>(options =>
{
[Link] = true;
});
var app = [Link]();
[Link]();
[Link]();
[Link] 14/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
Los tipos se comprueban al iniciar la aplicación con
IServiceProviderIsService a fin de determinar si un argumento de una
acción del controlador de API procede de la inserción de dependencias
o de otros orígenes.
El mecanismo para deducir el origen del enlace de los parámetros de la
acción del controlador de API utiliza estas reglas:
Nunca se sobrescribe una propiedad [Link].
[Link] se asigna a un parámetro de tipo
complejo, registrado en el contenedor de la inserción de
dependencias.
[Link] se asigna a un parámetro de tipo complejo,
no registrado en el contenedor de la inserción de dependencias.
[Link] se asigna a un parámetro con un nombre que
aparece como un valor de ruta en cualquier plantilla de ruta.
Todos los demás parámetros son [Link].
Deshabilitación de las reglas de inferencia
Para deshabilitar la inferencia del origen de enlace, establezca
SuppressInferBindingSourcesForParameters en true :
C#
using [Link];
var builder = [Link](args);
[Link]()
.ConfigureApiBehaviorOptions(options =>
{
[Link] =
true;
[Link] =
true;
[Link] = true;
[Link] 15/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[Link] = true;
[Link][StatusCodes.Status404NotFound].Li
nk =
"[Link]
[Link] =
true;
});
var app = [Link]();
[Link]();
[Link]();
[Link]();
[Link]();
Inferencia de solicitud de varios
elementos o datos de formulario
El atributo [ApiController] aplica una regla de inferencia para los
parámetros de acción de tipo IFormFile y IFormFileCollection. El tipo de
contenido de la solicitud multipart/form-data se infiere para estos
tipos.
Para deshabilitar el comportamiento predeterminado, establezca la
propiedad SuppressConsumesConstraintForFormFileParameters en
true :
C#
using [Link];
var builder = [Link](args);
[Link]()
.ConfigureApiBehaviorOptions(options =>
[Link] 16/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[Link] =
true;
[Link] =
true;
[Link] = true;
[Link] = true;
[Link][StatusCodes.Status404NotFound].Li
nk =
"[Link]
});
var app = [Link]();
[Link]();
[Link]();
[Link]();
[Link]();
Detalles de problemas de los códigos de
estado de error
MVC transforma un resultado de error (un resultado con un código de
estado 400 o superior) en un resultado con ProblemDetails. El tipo
ProblemDetails se basa en la especificación RFC 7807 para
proporcionar detalles de error de lectura mecánica en una respuesta
HTTP.
Observe el código siguiente en una acción de controlador:
C#
if (pet == null)
{
[Link] 17/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
return NotFound();
}
El método NotFound genera un código de estado HTTP 404 con un
cuerpo ProblemDetails . Por ejemplo:
JSON
{
type: "[Link]
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Deshabilitación de la respuesta ProblemDetails
La creación automática de ProblemDetails para los códigos de estado
de error está deshabilitada cuando la propiedad
SuppressMapClientErrors está establecida en true . Agregue el
siguiente código:
C#
using [Link];
var builder = [Link](args);
[Link]()
.ConfigureApiBehaviorOptions(options =>
{
[Link] =
true;
[Link] =
true;
[Link] = true;
[Link] = true;
[Link] 18/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
[Link][StatusCodes.Status404NotFound].Li
nk =
"[Link]
});
var app = [Link]();
[Link]();
[Link]();
[Link]();
[Link]();
Definición de tipos de contenido de la
solicitud compatibles con el atributo
[Consumes]
De forma predeterminada, una acción admite todos los tipos de
contenido de la solicitud disponibles. Por ejemplo, si una aplicación
está configurada para admitir formateadores de entrada JSON y XML,
una acción admite varios tipos de contenido, incluidos
application/json y application/xml .
El atributo [Consumes] permite que una acción limite los tipos de
contenido de la solicitud compatibles. Aplique el atributo [Consumes] a
una acción o controlador, especificando uno o varios tipos de
contenido:
C#
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
[Link] 19/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
En el código anterior, la acción CreateProduct especifica el tipo de
contenido application/xml . Las solicitudes enrutadas a esta acción
deben especificar un encabezado Content-Type de application/xml .
Las solicitudes que no especifican un encabezado Content-Type de
application/xml generan una respuesta 415 Tipo de medio no
compatible .
El atributo [Consumes] también permite que una acción influya en su
selección en función del tipo de contenido de una solicitud entrante
aplicando una restricción de tipo. Considere el ejemplo siguiente:
C#
[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
[HttpPost]
[Consumes("application/json")]
public IActionResult PostJson(IEnumerable<int> values)
=>
Ok(new { Consumes = "application/json", Values = va‐
lues });
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult PostForm([FromForm]
IEnumerable<int> values) =>
Ok(new { Consumes = "application/x-www-form-urlenco‐
ded", Values = values });
}
En el código anterior, ConsumesController se configura para controlar
las solicitudes enviadas a la dirección URL
[Link] . Las dos acciones del
controlador, PostJson y PostForm , controlan las solicitudes POST con
la misma dirección URL. Sin el atributo [Consumes] que aplica una
restricción de tipo, se produce una excepción de coincidencia ambigua.
[Link] 20/21
25/11/24, 11:18 p.m. Creación de API web con [Link] Core | Microsoft Learn
El atributo [Consumes] se aplica a ambas acciones. La acción PostJson
controla las solicitudes enviadas con un encabezado Content-Type de
application/json . La acción PostForm controla las solicitudes enviadas
con un encabezado Content-Type de application/x-www-form-
urlencoded .
Recursos adicionales
Vea o descargue el código de ejemplo . (Método de descarga).
Tipos de valor devuelto de acción del controlador en la API web
de [Link] Core
Control de errores en las API web basadas en el controlador de
[Link] Core
Formateadores personalizados en [Link] Core Web API
Aplicación de formato a datos de respuesta en [Link] Core
Web API
Documentación de la API web de [Link] Core con
Swagger/OpenAPI
Enrutar a acciones de controlador de [Link] Core
Uso de la tunelización de puertos de Visual Studio para depurar
API web
Creación de una API web con [Link] Core
[Link] 21/21