Mettre en forme les données des réponses dans l’API web ASP.NET CoreFormat response data in ASP.NET Core Web API

Par Steve SmithBy Steve Smith

ASP.NET Core MVC offre une prise en charge intégrée de la mise en forme des données des réponses, selon un format fixe ou en réponse à des spécifications du client.ASP.NET Core MVC has built-in support for formatting response data, using fixed formats or in response to client specifications.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Résultats d’une action spécifique à un formatFormat-Specific Action Results

Certains types de résultats d’action sont spécifiques à un format particulier, comme JsonResult et ContentResult.Some action result types are specific to a particular format, such as JsonResult and ContentResult. Les actions peuvent retourner des résultats spécifiques qui sont toujours mis en forme d’une manière particulière.Actions can return specific results that are always formatted in a particular manner. Par exemple, retourner un JsonResult retourne des données au format JSON, indépendamment des préférences du client.For example, returning a JsonResult will return JSON-formatted data, regardless of client preferences. De même, retourner un ContentResult retourne des données de chaîne au format texte brut (tout comme retourner une chaîne).Likewise, returning a ContentResult will return plain-text-formatted string data (as will simply returning a string).

Note

Une action ne doit pas nécessairement retourner un type particulier ; MVC prend en charge n’importe quelle valeur de retour d’un objet.An action isn't required to return any particular type; MVC supports any object return value. Si une action retourne une implémentation de IActionResult et que le contrôleur hérite de Controller, les développeurs disposent de nombreuses méthodes helper correspondant à de nombreux choix différents.If an action returns an IActionResult implementation and the controller inherits from Controller, developers have many helper methods corresponding to many of the choices. Les résultats provenant d’actions qui retournent des objets qui ne sont pas des types IActionResult sont sérialisés en utilisant l’implémentation appropriée de IOutputFormatter.Results from actions that return objects that are not IActionResult types will be serialized using the appropriate IOutputFormatter implementation.

Pour retourner des données dans un format spécifique depuis un contrôleur qui hérite de la classe de base Controller, utilisez la méthode helper intégrée Json pour retourner du JSON et Content pour du texte brut.To return data in a specific format from a controller that inherits from the Controller base class, use the built-in helper method Json to return JSON and Content for plain text. Votre méthode d’action doit retourner le type de résultat spécifique (par exemple JsonResult) ou IActionResult.Your action method should return either the specific result type (for instance, JsonResult) or IActionResult.

Retour de données au format JSON :Returning JSON-formatted data:

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

Exemple de réponse de cette action :Sample response from this action:

Onglet Réseau des Outils de développement dans Microsoft Edge montrant que le type de contenu de la réponse est application/json

Notez que le type de contenu de la réponse est application/json, qui apparaît à la fois dans la liste des requêtes du réseau et dans la section En-têtes de réponse.Note that the content type of the response is application/json, shown both in the list of network requests and in the Response Headers section. Notez également la liste des options présentées par le navigateur (dans ce cas, Microsoft Edge) dans l’en-tête Accept de la section des en-têtes de la requête.Also note the list of options presented by the browser (in this case, Microsoft Edge) in the Accept header in the Request Headers section. La technique actuelle ignore cet en-tête ; sa prise en compte est présentée ci-dessous.The current technique is ignoring this header; obeying it is discussed below.

Pour retourner des données mises en forme en texte brut, utilisez ContentResult et le helper Content :To return plain text formatted data, use ContentResult and the Content helper:

// GET api/authors/about
[HttpGet("About")]
public ContentResult About()
{
    return Content("An API listing authors of docs.asp.net.");
}

Une réponse de cette action :A response from this action:

Onglet Réseau des Outils de développement dans Microsoft Edge montrant que le type de contenu de la réponse est text/plain

Notez que dans ce cas, le Content-Type retourné est text/plain.Note in this case the Content-Type returned is text/plain. Vous pouvez également obtenir ce comportement en utilisant simplement un type de réponse chaîne :You can also achieve this same behavior using just a string response type:

// GET api/authors/version
[HttpGet("version")]
public string Version()
{
    return "Version 1.0.0";
}

Conseil

Pour les actions plus complexes avec plusieurs types ou options (par exemple différents codes d’état HTTP en fonction du résultat des opérations effectuées), préférez le type de retour IActionResult.For non-trivial actions with multiple return types or options (for example, different HTTP status codes based on the result of operations performed), prefer IActionResult as the return type.

Négociation de contenuContent Negotiation

La négociation de contenu (conneg, abréviation de « Content negotiation ») se produit quand le client spécifie un en-tête Accept.Content negotiation (conneg for short) occurs when the client specifies an Accept header. Le format par défaut utilisé par ASP.NET Core MVC est JSON.The default format used by ASP.NET Core MVC is JSON. La négociation de contenu est implémentée par ObjectResult.Content negotiation is implemented by ObjectResult. Elle est également intégrée dans les résultats d’une action spécifique au code d’état retournés depuis les méthodes helper (qui sont toutes basées sur ObjectResult).It's also built into the status code specific action results returned from the helper methods (which are all based on ObjectResult). Vous pouvez aussi retourner un type de modèle (une classe que vous avez définie comme étant le type de transfert de vos données), que le framework encapsule automatiquement dans un ObjectResult pour vous.You can also return a model type (a class you've defined as your data transfer type) and the framework will automatically wrap it in an ObjectResult for you.

La méthode d’action suivante utilise les méthodes helper Ok et NotFound :The following action method uses the Ok and NotFound helper methods:

// GET: api/authors/search?namelike=th
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
    var result = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

Une réponse au format JSON est retournée sauf si un autre format a été demandé et que le serveur peut retourner ce format demandé.A JSON-formatted response will be returned unless another format was requested and the server can return the requested format. Vous pouvez utiliser un outil comme Fiddler pour créer une requête qui inclut un en-tête Accept et pour spécifier un autre format.You can use a tool like Fiddler to create a request that includes an Accept header and specify another format. Dans ce cas, si le serveur a un formateur qui peut produire une réponse dans le format demandé, le résultat est retourné dans le format préféré du client.In that case, if the server has a formatter that can produce a response in the requested format, the result will be returned in the client-preferred format.

Console Fiddler montrant une requête GET créée manuellement une valeur d’en-tête Accept application/xml

Dans la capture d’écran ci-dessus, Fiddler Composer a été utilisé pour générer une requête, en spécifiant Accept: application/xml.In the above screenshot, the Fiddler Composer has been used to generate a request, specifying Accept: application/xml. Par défaut, ASP.NET Core MVC prend en charge seulement JSON : même si un autre format est spécifié, le résultat retourné est donc toujours au format JSON.By default, ASP.NET Core MVC only supports JSON, so even when another format is specified, the result returned is still JSON-formatted. Vous verrez comment ajouter d’autres formateurs dans la section suivante.You'll see how to add additional formatters in the next section.

Les actions du contrôleur peuvent retourner des objets OCT (objets CLR traditionnels), auquel cas ASP.NET Core MVC crée automatiquement pour vous un ObjectResult qui encapsule l’objet.Controller actions can return POCOs (Plain Old CLR Objects), in which case ASP.NET Core MVC automatically creates an ObjectResult for you that wraps the object. Le client reçoit l’objet sérialisé mis en forme (le format JSON est le format par défaut ; vous pouvez configurer un format XML ou d’autres formats).The client will get the formatted serialized object (JSON format is the default; you can configure XML or other formats). Si l’objet retourné est null, le framework retourne une réponse 204 No Content.If the object being returned is null, then the framework will return a 204 No Content response.

Retour d’un type d’objet :Returning an object type:

// GET api/authors/ardalis
[HttpGet("{alias}")]
public Author Get(string alias)
{
    return _authorRepository.GetByAlias(alias);
}

Dans l’exemple, une requête d’alias d’auteur valide reçoit une réponse 200 OK avec les données de l’auteur.In the sample, a request for a valid author alias will receive a 200 OK response with the author's data. Une requête d’alias non valide reçoit une réponse 204 No Content.A request for an invalid alias will receive a 204 No Content response. Les captures d’écran ci-dessous montrent la réponse aux formats XML et JSON.Screenshots showing the response in XML and JSON formats are shown below.

Processus de négociation de contenuContent Negotiation Process

La négociation de contenu intervient seulement si un en-tête Accept apparaît dans la requête.Content negotiation only takes place if an Accept header appears in the request. Quand une requête contient un en-tête Accept, le framework énumère les types de médias dans l’en-tête Accept par ordre de préférence, et tente de trouver un formateur capable de produire une réponse dans un des formats spécifiés par l’en-tête Accept.When a request contains an accept header, the framework will enumerate the media types in the accept header in preference order and will try to find a formatter that can produce a response in one of the formats specified by the accept header. Si aucun formateur pouvant satisfaire la requête du client n’est trouvé, le framework tente de trouver le premier formateur capable de produire une réponse (sauf si le développeur a configuré l’option sur MvcOptions pour retourner à la place « 406 Not Acceptable »).In case no formatter is found that can satisfy the client's request, the framework will try to find the first formatter that can produce a response (unless the developer has configured the option on MvcOptions to return 406 Not Acceptable instead). Si la requête spécifie XML, mais que le formateur XML n’a pas été configuré, le formateur JSON est utilisé.If the request specifies XML, but the XML formatter has not been configured, then the JSON formatter will be used. Plus généralement, si aucun formateur pouvant fournir le format demandé n’est configuré, le premier formateur qui peut mettre en forme l’objet est utilisé.More generally, if no formatter is configured that can provide the requested format, then the first formatter that can format the object is used. Si aucun en-tête n’est spécifié, le premier formateur capable de gérer l’objet à retourner est utilisé pour sérialiser la réponse.If no header is given, the first formatter that can handle the object to be returned will be used to serialize the response. Dans ce cas, aucune négociation n’est effectuée : le serveur détermine le format à utiliser.In this case, there isn't any negotiation taking place - the server is determining what format it will use.

Note

Si l’en-tête Accept contient */*, l’en-tête est ignoré, sauf si RespectBrowserAcceptHeader a la valeur true sur MvcOptions.If the Accept header contains */*, the Header will be ignored unless RespectBrowserAcceptHeader is set to true on MvcOptions.

Navigateurs et négociation de contenuBrowsers and Content Negotiation

Contrairement aux clients d’API classiques, les navigateurs web ont tendance à fournir des en-têtes Accept dans un grand nombre de formats, incluant des caractères génériques.Unlike typical API clients, web browsers tend to supply Accept headers that include a wide array of formats, including wildcards. Par défaut, quand le framework détecte que la requête provient d’un navigateur, il ignore l’en-tête Accept et retourne à la place le contenu au format par défaut configuré pour l’application (JSON, sauf si un autre format est configuré).By default, when the framework detects that the request is coming from a browser, it will ignore the Accept header and instead return the content in the application's configured default format (JSON unless otherwise configured). Ceci fournit une expérience plus cohérente lors de l’utilisation de différents navigateurs pour consommer des API.This provides a more consistent experience when using different browsers to consume APIs.

Si vous préférez que votre application prenne en compte les en-têtes Accept du navigateur, vous pouvez configurer ce comportement dans le cadre de la configuration du modèle MVC en définissant RespectBrowserAcceptHeader sur true dans la méthode ConfigureServices, dans Startup.cs.If you would prefer your application honor browser accept headers, you can configure this as part of MVC's configuration by setting RespectBrowserAcceptHeader to true in the ConfigureServices method in Startup.cs.

services.AddMvc(options =>
{
    options.RespectBrowserAcceptHeader = true; // false by default
});

Configuration des formateursConfiguring Formatters

Si votre application doit prendre en charge des formats supplémentaires en plus du format par défaut JSON, vous pouvez ajouter des packages NuGet et configurer le modèle MVC pour les prendre en charge.If your application needs to support additional formats beyond the default of JSON, you can add NuGet packages and configure MVC to support them. Il existe des formateurs distincts pour les entrées et pour les sorties.There are separate formatters for input and output. Les formateurs d’entrée sont utilisés par la liaison de modèle ; les formateurs de sortie sont utilisés pour mettre en forme les réponses.Input formatters are used by Model Binding; output formatters are used to format responses. Vous pouvez également configurer des formateurs personnalisés.You can also configure Custom Formatters.

Ajout de la prise en charge du format XMLAdding XML Format Support

Pour ajouter la prise en charge de la mise en forme XML, vous devez installer le package NuGet Microsoft.AspNetCore.Mvc.Formatters.Xml.To add support for XML formatting, install the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

Ajoutez XmlSerializerFormatters à la configuration du modèle MVC à Startup.cs :Add the XmlSerializerFormatters to MVC's configuration in Startup.cs:

services.AddMvc()
    .AddXmlSerializerFormatters();

Vous pouvez aussi ajouter simplement le formateur de sortie :Alternately, you can add just the output formatter:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});

Ces deux approches sérialisent les résultats avec System.Xml.Serialization.XmlSerializer.These two approaches will serialize results using System.Xml.Serialization.XmlSerializer. Si vous préférez, vous pouvez utiliser System.Runtime.Serialization.DataContractSerializer en ajoutant son formateur associé :If you prefer, you can use the System.Runtime.Serialization.DataContractSerializer by adding its associated formatter:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
});

Une fois que vous avez ajouté la prise en charge de la mise en forme XML, vos méthodes de contrôleur doivent retourner le format approprié en fonction de l’en-tête Accept de la requête, comme cet exemple Fiddler le montre :Once you've added support for XML formatting, your controller methods should return the appropriate format based on the request's Accept header, as this Fiddler example demonstrates:

Console Fiddler : l’onglet Raw pour la requête montre que la valeur de l’en-tête Accept est application/xml.

Vous pouvez voir dans l’onglet Inspectors que la requête GET brute a été faite avec un en-tête Accept: application/xml.You can see in the Inspectors tab that the Raw GET request was made with an Accept: application/xml header set. Le volet de réponse montre l’en-tête Content-Type: application/xml et que l’objet Author a été sérialisé en XML.The response pane shows the Content-Type: application/xml header, and the Author object has been serialized to XML.

Utilisez l’onglet Composer pour modifier la requête en spécifiant application/json dans l’en-tête Accept.Use the Composer tab to modify the request to specify application/json in the Accept header. Exécutez la requête pour constater que la réponse est au format JSON :Execute the request, and the response will be formatted as JSON:

Console Fiddler : l’onglet Raw pour la requête montre que la valeur de l’en-tête Accept est application/json.

Dans cette capture d’écran, vous pouvez voir que la requête définit un en-tête Accept: application/json et que la réponse spécifie de même dans son Content-Type.In this screenshot, you can see the request sets a header of Accept: application/json and the response specifies the same as its Content-Type. L’objet Author est montré dans le corps de la réponse, au format JSON.The Author object is shown in the body of the response, in JSON format.

Forçer un format particulierForcing a Particular Format

Si vous voulez limiter les formats de réponse pour une action spécifique, vous pouvez appliquer le filtre [Produces].If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. Le filtre [Produces] spécifie les formats de réponse pour une action (ou un contrôleur) spécifique.The [Produces] filter specifies the response formats for a specific action (or controller). Comme la plupart des filtres, celui-ci peut être appliqué à l’action, au contrôleur ou à l’étendue globale.Like most Filters, this can be applied at the action, controller, or global scope.

[Produces("application/json")]
public class AuthorsController

Le filtre [Produces] force toutes les actions dans AuthorsController à retourner des réponses au format JSON, même si d’autres formateurs ont été configurés pour l’application et que le client a fourni un en-tête Accept demandant un autre format disponible.The [Produces] filter will force all actions within the AuthorsController to return JSON-formatted responses, even if other formatters were configured for the application and the client provided an Accept header requesting a different, available format. Pour plus d’informations, notamment comment appliquer des filtres de façon globale, consultez Filtres.See Filters to learn more, including how to apply filters globally.

Formateurs pour des cas spéciauxSpecial Case Formatters

Certains cas spéciaux sont implémentés avec des formateurs intégrés.Some special cases are implemented using built-in formatters. Par défaut, les types de retour string sont formatés en text/plain (text/html si c’est demandé via l’en-tête Accept).By default, string return types will be formatted as text/plain (text/html if requested via Accept header). Vous pouvez éviter ce comportement en supprimant TextOutputFormatter.This behavior can be removed by removing the TextOutputFormatter. Vous supprimez des formateurs dans la méthode Configure de Startup.cs (voir ci-dessous).You remove formatters in the Configure method in Startup.cs (shown below). Les actions qui ont un type de retour d’objet de modèle retournent une réponse « 204 No Content » si null est retourné.Actions that have a model object return type will return a 204 No Content response when returning null. Vous pouvez éviter ce comportement en supprimant HttpNoContentOutputFormatter.This behavior can be removed by removing the HttpNoContentOutputFormatter. Le code suivant supprime TextOutputFormatter et HttpNoContentOutputFormatter.The following code removes the TextOutputFormatter and HttpNoContentOutputFormatter.

services.AddMvc(options =>
{
    options.OutputFormatters.RemoveType<TextOutputFormatter>();
    options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});

Par exemple, sans TextOutputFormatter, les types de retour string retournent « 406 Not Acceptable ».Without the TextOutputFormatter, string return types return 406 Not Acceptable, for example. Notez que s’il existe un formateur XML, il met en forme les types de retour string si TextOutputFormatter est supprimé.Note that if an XML formatter exists, it will format string return types if the TextOutputFormatter is removed.

Sans HttpNoContentOutputFormatter, les objets null sont mis en forme avec le formateur configuré.Without the HttpNoContentOutputFormatter, null objects are formatted using the configured formatter. Par exemple, le formateur JSON retourne simplement une réponse avec un corps null, tandis que le formateur XML retourne un élément XML vide avec l’attribut xsi:nil="true".For example, the JSON formatter will simply return a response with a body of null, while the XML formatter will return an empty XML element with the attribute xsi:nil="true" set.

Mappages d’URL de format de réponseResponse Format URL Mappings

Les clients peuvent demander un format particulier dans l’URL, comme dans la chaîne de requête ou une partie du chemin, ou en utilisant une extension de fichier spécifique à un format, comme .xml ou .json.Clients can request a particular format as part of the URL, such as in the query string or part of the path, or by using a format-specific file extension such as .xml or .json. Le mappage du chemin de la requête doit être spécifié dans la route utilisée par l’API.The mapping from request path should be specified in the route the API is using. Exemple :For example:

[FormatFilter]
public class ProductsController
{
    [Route("[controller]/[action]/{id}.{format?}")]
    public Product GetById(int id)

Cette route permet de spécifier le format demandé sous la forme d’une extension de fichier facultative.This route would allow the requested format to be specified as an optional file extension. L’attribut [FormatFilter] vérifie l’existence de la valeur du format dans RouteData et mappe le format de la réponse au formateur approprié lors de la création de la réponse.The [FormatFilter] attribute checks for the existence of the format value in the RouteData and will map the response format to the appropriate formatter when the response is created.

RouteRoute FormateurFormatter
/products/GetById/5 Le formateur de sortie par défautThe default output formatter
/products/GetById/5.json Le formateur JSON (s’il est configuré)The JSON formatter (if configured)
/products/GetById/5.xml Le formateur XML (s’il est configuré)The XML formatter (if configured)