Créer des API web avec ASP.NET CoreCreate web APIs with ASP.NET Core

De Scott Addie et Tom DykstraBy Scott Addie and Tom Dykstra

ASP.NET Core prend en charge la création de services RESTful, également appelés API web, à l’aide de C#.ASP.NET Core supports creating RESTful services, also known as web APIs, using C#. Pour traiter les demandes, une API web utilise des contrôleurs.To handle requests, a web API uses controllers. Les contrôleurs dans une API web sont des classes qui dérivent de ControllerBase.Controllers in a web API are classes that derive from ControllerBase. Cet article explique comment utiliser des contrôleurs pour gérer les demandes d’API Web.This article shows how to use controllers for handling web API requests.

Affichez ou téléchargez l’exemple de code.View or download sample code. (Guide pratique de téléchargement).(How to download).

Classe ControllerBaseControllerBase class

Une API Web se compose d’une ou de plusieurs classes de contrôleur ControllerBasequi dérivent de.A web API consists of one or more controller classes that derive from ControllerBase. Le modèle de projet d’API Web fournit un contrôleur de démarrage :The web API project template provides a starter controller:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Ne créez pas de contrôleur d’API web en effectuant une dérivation de la classe Controller.Don't create a web API controller by deriving from the Controller class. Controller dérive de ControllerBase et ajoute la prise en charge pour les vues ; ainsi, il est destiné à la gestion des pages web, pas des demandes d’API web.Controller derives from ControllerBase and adds support for views, so it's for handling web pages, not web API requests. Il existe une exception à cette règle : Si vous envisagez d’utiliser le même contrôleur pour les vues et les API Web, Controllerdérivez-le de.There's an exception to this rule: if you plan to use the same controller for both views and web APIs, derive it from Controller.

La classe ControllerBase fournit de nombreuses propriétés et méthodes qui sont utiles pour gérer les requêtes HTTP.The ControllerBase class provides many properties and methods that are useful for handling HTTP requests. Par exemple, ControllerBase.CreatedAtAction retourne un code d’état 201 :For example, ControllerBase.CreatedAtAction returns a 201 status code:

[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
    pet.Id = _petsInMemoryStore.Any() ? 
             _petsInMemoryStore.Max(p => p.Id) + 1 : 1;
    _petsInMemoryStore.Add(pet);

    return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}

Voici d’autres exemples de méthodes fournies par ControllerBase.Here are some more examples of methods that ControllerBase provides.

MéthodeMethod NotesNotes
BadRequest Retourne le code d’état 400.Returns 400 status code.
NotFound Retourne le code d’état 404.Returns 404 status code.
PhysicalFile Retourne un fichier.Returns a file.
TryUpdateModelAsync Appelle la liaison de modèle.Invokes model binding.
TryValidateModel Appelle la validation de modèle.Invokes model validation.

Pour obtenir la liste complète des méthodes et propriétés disponibles, consultez ControllerBase.For a list of all available methods and properties, see ControllerBase.

AttributsAttributes

L’espace de noms Microsoft.AspNetCore.Mvc fournit des attributs qui peuvent être utilisés pour configurer le comportement des contrôleurs d’API web et des méthodes d’action.The Microsoft.AspNetCore.Mvc namespace provides attributes that can be used to configure the behavior of web API controllers and action methods. L’exemple suivant utilise des attributs pour spécifier le verbe d’action HTTP pris en charge et tous les codes d’état HTTP connus qui peuvent être retournés :The following example uses attributes to specify the supported HTTP action verb and any known HTTP status codes that could be returned:

[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
    pet.Id = _petsInMemoryStore.Any() ? 
             _petsInMemoryStore.Max(p => p.Id) + 1 : 1;
    _petsInMemoryStore.Add(pet);

    return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}

Voici d’autres exemples d’attributs disponibles.Here are some more examples of attributes that are available.

AttributAttribute NotesNotes
[Route][Route] Spécifie le modèle d’URL pour un contrôleur ou une action.Specifies URL pattern for a controller or action.
[Bind][Bind] Spécifie le préfixe et les propriétés à inclure pour la liaison de modèle.Specifies prefix and properties to include for model binding.
[HttpGet][HttpGet] Identifie une action qui prend en charge le verbe d’action HTTP.Identifies an action that supports the HTTP GET action verb.
[Consumes][Consumes] Spécifie les types de données acceptés par une action.Specifies data types that an action accepts.
[Produces][Produces] Spécifie les types de données retournés par une action.Specifies data types that an action returns.

Pour obtenir la liste des attributs disponibles, consultez l’espace de noms Microsoft.AspNetCore.Mvc.For a list that includes the available attributes, see the Microsoft.AspNetCore.Mvc namespace.

Attribut ApiControllerApiController attribute

L’attribut [ApiController] peut être appliqué à une classe de contrôleur pour activer les consignes strictes suivants, comportements spécifiques aux API :The [ApiController] attribute can be applied to a controller class to enable the following opinionated, API-specific behaviors:

Ces fonctionnalités nécessitent une version de compatibilité 2.1 ou ultérieure.These features require a compatibility version of 2.1 or later.

Attribut sur des contrôleurs spécifiquesAttribute on specific controllers

L’attribut [ApiController] peut être appliqué à des contrôleurs spécifiques, comme dans l’exemple suivant à partir du modèle de projet :The [ApiController] attribute can be applied to specific controllers, as in the following example from the project template:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Attribut sur plusieurs contrôleursAttribute on multiple controllers

Une façon d’utiliser l’attribut sur plusieurs contrôleurs consiste à créer une classe de contrôleur de base personnalisée annotée avec l’attribut [ApiController].One approach to using the attribute on more than one controller is to create a custom base controller class annotated with the [ApiController] attribute. L’exemple suivant montre une classe de base personnalisée et un contrôleur qui dérive de celle-ci :The following example shows a custom base class and a controller that derives from it:

[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
[Produces(MediaTypeNames.Application.Json)]
[Route("api/[controller]")]
public class PetsController : MyControllerBase

Attribut sur un assemblyAttribute on an assembly

Si la version de compatibilité est définie sur 2.2 ou une version ultérieure, l’attribut [ApiController] peut être appliqué à un assembly.If compatibility version is set to 2.2 or later, the [ApiController] attribute can be applied to an assembly. De cette manière, l’annotation applique le comportement de l’API web à tous les contrôleurs de l’assembly.Annotation in this manner applies web API behavior to all controllers in the assembly. Les contrôleurs individuels n’ont aucun moyen de refuser.There's no way to opt out for individual controllers. Appliquez l’attribut assembly au niveau de l’assembly à Startup la déclaration d’espace de noms qui entoure la classe :Apply the assembly-level attribute to the namespace declaration surrounding the Startup class:

[assembly: ApiController]
namespace WebApiSample
{
    public class Startup
    {
        ...
    }
}

Exigence du routage d’attributAttribute routing requirement

L’attribut [ApiController] rend nécessaire le routage d’attributs.The [ApiController] attribute makes attribute routing a requirement. Par exemple :For example:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

Les actions sont inaccessibles par le biais UseEndpointsdes UseMvc itinéraires conventionnels définis par, ou UseMvcWithDefaultRoute dans Startup.Configure.Actions are inaccessible via conventional routes defined by UseEndpoints, UseMvc, or UseMvcWithDefaultRoute in Startup.Configure.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Les actions sont inaccessibles par le biais de routes conventionnelles définies par UseMvc ou UseMvcWithDefaultRoute dans Startup.Configure.Actions are inaccessible via conventional routes defined by UseMvc or UseMvcWithDefaultRoute in Startup.Configure.

Réponses HTTP 400 automatiquesAutomatic HTTP 400 responses

Grâce à l’attribut [ApiController], les erreurs de validation de modèles déclenchent automatiquement une réponse HTTP 400.The [ApiController] attribute makes model validation errors automatically trigger an HTTP 400 response. Ainsi, le code suivant est inutile dans une méthode d’action :Consequently, the following code is unnecessary in an action method:

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}

ASP.net Core MVC utilise le ModelStateInvalidFilter filtre d’action pour effectuer la vérification précédente.ASP.NET Core MVC uses the ModelStateInvalidFilter action filter to do the preceding check.

Réponse BadRequest par défautDefault BadRequest response

Avec une version de compatibilité de 2,1, le type de réponse par défaut pour une réponse SerializableErrorhttp 400 est.With a compatibility version of 2.1, the default response type for an HTTP 400 response is SerializableError. Le corps de la requête suivant est un exemple de type sérialisé :The following request body is an example of the serialized type:

{
  "": [
    "A non-empty request body is required."
  ]
}

Avec une version de compatibilité 2,2 ou ultérieure, le type de réponse par défaut pour une réponse HTTP ValidationProblemDetails400 est.With a compatibility version of 2.2 or later, the default response type for an HTTP 400 response is ValidationProblemDetails. Le corps de la requête suivant est un exemple de type sérialisé :The following request body is an example of the serialized type:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|7fb5e16a-4c8f23bbfc974667.",
  "errors": {
    "": [
      "A non-empty request body is required."
    ]
  }
}

ValidationProblemDetails Type :The ValidationProblemDetails type:

  • Fournit un format lisible par l’ordinateur pour spécifier les erreurs dans les réponses de l’API Web.Provides a machine-readable format for specifying errors in web API responses.
  • Est conforme à la spécification RFC 7807.Complies with the RFC 7807 specification.

Consigner automatiquement 400 réponsesLog automatic 400 responses

Voir Guide pratique pour consigner automatiquement 400 réponses en cas d’erreurs de validation de modèle (aspnet/AspNetCore.Docs no 12157).See How to log automatic 400 responses on model validation errors (aspnet/AspNetCore.Docs #12157).

Désactiver la réponse automatique 400Disable automatic 400 response

Pour désactiver le comportement 400 automatique, définissez la propriété SuppressModelStateInvalidFilter sur true.To disable the automatic 400 behavior, set the SuppressModelStateInvalidFilter property to true. Ajoutez le code en surbrillance suivant dans Startup.ConfigureServices :Add the following highlighted code in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });

Inférence de paramètre de source de liaisonBinding source parameter inference

Un attribut de source de liaison définit l’emplacement auquel se trouve la valeur d’un paramètre d’action.A binding source attribute defines the location at which an action parameter's value is found. Les attributs de source de liaison suivants existent :The following binding source attributes exist:

AttributAttribute Source de liaisonBinding source
[FromBody][FromBody] Corps de la requêteRequest body
[FromForm][FromForm] Données de formulaire dans le corps de la demandeForm data in the request body
[FromHeader][FromHeader] En-tête de demandeRequest header
[FromQuery][FromQuery] Paramètre de la chaîne de requête de la demandeRequest query string parameter
[FromRoute][FromRoute] Données d’itinéraire à partir de la demande actuelleRoute data from the current request
[FromServices][FromServices] Service de demande injecté comme paramètre d’actionThe request service injected as an action parameter

Avertissement

N’utilisez pas [FromRoute] lorsque les valeurs risquent de contenir %2f (c’est-à-dire /).Don't use [FromRoute] when values might contain %2f (that is /). %2f ne sera pas sans la séquence d’échappement /.%2f won't be unescaped to /. Utilisez [FromQuery] si la valeur peut contenir %2f.Use [FromQuery] if the value might contain %2f.

Sans l’attribut [ApiController] ou des attributs de source de liaison comme [FromQuery], le runtime ASP.NET Core tente d’utiliser le classeur de modèles objet complexe.Without the [ApiController] attribute or binding source attributes like [FromQuery], the ASP.NET Core runtime attempts to use the complex object model binder. Le classeur de modèles objet complexe extrait des données à partir de fournisseurs de valeurs dans un ordre défini.The complex object model binder pulls data from value providers in a defined order.

Dans l’exemple suivant, l’attribut [FromQuery] indique que la valeur du paramètre discontinuedOnly est fournie dans la chaîne de requête de l’URL de demande :In the following example, the [FromQuery] attribute indicates that the discontinuedOnly parameter value is provided in the request URL's query string:

[HttpGet]
public ActionResult<List<Product>> Get(
    [FromQuery] bool discontinuedOnly = false)
{
    List<Product> products = null;

    if (discontinuedOnly)
    {
        products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
    }
    else
    {
        products = _productsInMemoryStore;
    }

    return products;
}

L’attribut [ApiController] applique des règles d’inférence pour les sources de données par défaut des paramètres d’action.The [ApiController] attribute applies inference rules for the default data sources of action parameters. Ces règles vous évitent d’avoir à identifier les sources de liaison manuellement en appliquant des attributs aux paramètres d’action.These rules save you from having to identify binding sources manually by applying attributes to the action parameters. Les règles d’inférence de source de liaison se comportent comme suit :The binding source inference rules behave as follows:

  • [FromBody] est déduit des paramètres de type complexe.[FromBody] is inferred for complex type parameters. Une exception à cette règle d’inférence [FromBody] est tout type complexe intégré ayant une signification spéciale, comme IFormCollection et CancellationToken.An exception to the [FromBody] inference rule is any complex, built-in type with a special meaning, such as IFormCollection and CancellationToken. Le code de l’inférence de la source de liaison ignore ces types spéciaux.The binding source inference code ignores those special types.
  • [FromForm] est déduit pour les paramètres d’action de type IFormFile et IFormFileCollection.[FromForm] is inferred for action parameters of type IFormFile and IFormFileCollection. Il n’est pas déduit pour les types simples ou définis par l’utilisateur.It's not inferred for any simple or user-defined types.
  • [FromRoute] est déduit pour tout nom de paramètre d’action correspondant à un paramètre dans le modèle d’itinéraire.[FromRoute] is inferred for any action parameter name matching a parameter in the route template. Quand plus d’un itinéraire correspond à un paramètre d’action, toute valeur d’itinéraire est considérée comme [FromRoute].When more than one route matches an action parameter, any route value is considered [FromRoute].
  • [FromQuery] est déduit pour tous les autres paramètres d’action.[FromQuery] is inferred for any other action parameters.

Notes sur l’inférence FromBodyFromBody inference notes

[FromBody] n’est pas déduit pour les types simples tels que string ou int.[FromBody] isn't inferred for simple types such as string or int. Vous devez donc utiliser l’attribut [FromBody] pour les types simples quand cette fonctionnalité est nécessaire.Therefore, the [FromBody] attribute should be used for simple types when that functionality is needed.

Quand une action a plusieurs paramètres liés à partir du corps de la demande, une exception est levée.When an action has more than one parameter bound from the request body, an exception is thrown. Par exemple, toutes les signatures de méthode d’action suivantes génèrent une exception :For example, all of the following action method signatures cause an exception:

  • [FromBody] est déduit sur les deux paramètres, car ce sont des types complexes.[FromBody] inferred on both because they're complex types.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • Attribut [FromBody] sur un paramètre, déduit sur l’autre, car c’est un type complexe.[FromBody] attribute on one, inferred on the other because it's a complex type.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • Attribut [FromBody] sur les deux paramètres.[FromBody] attribute on both.

    [HttpPost]
    public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
    

Notes

Dans ASP.NET Core 2.1, les paramètres de type collection comme les listes et les tableaux sont déduits de manière incorrecte en tant que [FromQuery].In ASP.NET Core 2.1, collection type parameters such as lists and arrays are incorrectly inferred as [FromQuery]. L’attribut [FromBody] doit être utilisé pour ces paramètres s’ils doivent être liés à partir du corps de la demande.The [FromBody] attribute should be used for these parameters if they are to be bound from the request body. Ce problème est corrigé dans ASP.NET Core version 2.2 ou ultérieure, où les paramètres de type collection sont déduits pour être liés à partir du corps par défaut.This behavior is corrected in ASP.NET Core 2.2 or later, where collection type parameters are inferred to be bound from the body by default.

Désactiver les règles d’inférenceDisable inference rules

Pour désactiver l’inférence de la source de liaison, définissez SuppressInferBindingSourcesForParameters sur true.To disable binding source inference, set SuppressInferBindingSourcesForParameters to true. Ajoutez le code suivant dans Startup.ConfigureServices :Add the following code in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });

Inférence de demande multipart/form-dataMultipart/form-data request inference

L' [ApiController] attribut applique une règle d’inférence lorsqu’un paramètre d’action est annoté avec l’attribut [FromForm] .The [ApiController] attribute applies an inference rule when an action parameter is annotated with the [FromForm] attribute. Le multipart/form-data type de contenu de la demande est déduit.The multipart/form-data request content type is inferred.

Pour désactiver le comportement par défaut, affectez à true la Startup.ConfigureServicespropriété la SuppressConsumesConstraintForFormFileParameters valeur dans :To disable the default behavior, set the SuppressConsumesConstraintForFormFileParameters property to true in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });

Fonctionnalité Détails du problème pour les codes d’état erreurProblem details for error status codes

Quand la version de compatibilité est 2.2 ou ultérieure, MVC transforme un résultat d’erreur (résultat avec un code d’état égal ou supérieur à 400) en résultat avec ProblemDetails.When the compatibility version is 2.2 or later, MVC transforms an error result (a result with status code 400 or higher) to a result with ProblemDetails. Le type ProblemDetails est basé sur la spécification RFC 7807 pour fournir des détails de l’erreur lisibles par machine dans une réponse HTTP.The ProblemDetails type is based on the RFC 7807 specification for providing machine-readable error details in an HTTP response.

Prenons le code suivant dans une action de contrôleur :Consider the following code in a controller action:

if (pet == null)
{
    return NotFound();
}

La NotFound méthode génère un code d’état HTTP 404 avec ProblemDetails un corps.The NotFound method produces an HTTP 404 status code with a ProblemDetails body. Par exemple :For example:

{
  type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  title: "Not Found",
  status: 404,
  traceId: "0HLHLV31KRN83:00000001"
}

Désactiver la réponse ProblemDetailsDisable ProblemDetails response

La création automatique d’une ProblemDetails instance est désactivée SuppressMapClientErrors lorsque la propriété a truela valeur.The automatic creation of a ProblemDetails instance is disabled when the SuppressMapClientErrors property is set to true. Ajoutez le code suivant dans Startup.ConfigureServices :Add the following code in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });

Ressources supplémentairesAdditional resources