Partager via


Bien démarrer avec Swashbuckle et ASP.NET Core

Remarque

Swashbuckle n’est pas disponible dans .NET 9 et versions ultérieures. Pour une alternative, voir Vue d’ensemble de la prise en charge d’OpenAPI dans les applications API ASP.NET Core.

Swashbuckle repose sur trois composants principaux :

  • Swashbuckle.AspNetCore.Swagger : modèle objet Swagger et intergiciel (middleware) pour exposer des objets SwaggerDocument sous forme de points de terminaison JSON.

  • Swashbuckle.AspNetCore.SwaggerGen : générateur Swagger qui crée des objets SwaggerDocument directement à partir de vos routes, contrôleurs et modèles. Ce composant est généralement associé à l’intergiciel du point de terminaison Swagger pour exposer automatiquement un fichier JSON Swagger.

  • Swashbuckle.AspNetCore.SwaggerUI: version incorporée de l’outil IU Swagger. Il interprète le fichier JSON Swagger afin de créer une expérience enrichie et personnalisable permettant de décrire les fonctionnalités de l’API web. Il intègre des ateliers de test pour les méthodes publiques.

Installation de package

Vous pouvez ajouter Swashbuckle en adoptant l’une des approches suivantes :

  • À partir de la fenêtre Console du Gestionnaire de package :

    • Accédez à Affichage>Autres fenêtres>Console du Gestionnaire de package.

    • Accédez au répertoire où se trouve le fichier .csproj.

    • Exécutez la commande suivante :

      Install-Package Swashbuckle.AspNetCore -Version 6.6.2
      
  • À partir de la boîte de dialogue Gérer les packages NuGet :

    • Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions>Gérer les packages NuGet.
    • Affectez la valeur « nuget.org » à Source du package.
    • Vérifiez que l’option « Inclure la version préliminaire » est activée
    • Entrez « Swashbuckle.AspNetCore » dans la zone de recherche.
    • Sélectionnez le package « Swashbuckle.AspNetCore » le plus récent sous l’onglet Parcourir et cliquez sur Installer.

Ajouter et configurer l’intergiciel (middleware) Swagger

Ajoutez le générateur Swagger à la collection de services dans Program.cs :

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

L’appel à AddEndpointsApiExplorer présenté dans l’exemple précédent est requis uniquement pour les API minimales. Pour plus d’informations, consultez ce billet StackOverflow.

Activez l’intergiciel pour traiter le document JSON généré et l’interface utilisateur de Swagger, également dans Program.cs :

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

Le code précédent n’ajoute le middleware Swagger que si l’environnement actuel est défini sur Development. L’appel de méthode UseSwaggerUI active une version incorporée de l’outil d’interface utilisateur Swagger.

Lancez l’application et accédez à https://localhost:<port>/swagger/v1/swagger.json. Le document généré décrivant les points de terminaison s’affiche comme dans la spécification OpenAPI (openapi.json).

L’interface utilisateur Swagger se trouve à l’adresse https://localhost:<port>/swagger. Explorez l’API via l’interface utilisateur Swagger et incorporez-la dans d’autres programmes.

Conseil

Pour utiliser l’IU Swagger à la racine de l’application (https://localhost:<port>/), définissez la propriété RoutePrefix sur une chaîne vide :

if (builder.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options => // UseSwaggerUI is called only in Development.
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
        options.RoutePrefix = string.Empty;
    });
}

Si vous utilisez des répertoires avec IIS ou un proxy inverse, définissez le point de terminaison Swagger sur un chemin relatif avec le préfixe ./. Par exemple : ./swagger/v1/swagger.json. L’utilisation de /swagger/v1/swagger.json indique à l’application de rechercher le fichier JSON à la racine réelle de l’URL (plus le préfixe de la route s’il est utilisé). Par exemple, utilisez https://localhost:<port>/<route_prefix>/swagger/v1/swagger.json au lieu de https://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Remarque

Par défaut, Swashbuckle génère et expose Swagger JSON dans la version 3.0 de la spécification, officiellement appelée spécification OpenAPI. Pour prendre en charge la compatibilité descendante, vous pouvez choisir d’exposer JSON au format 2.0. Ce format 2.0 est important pour les intégrations telles que Microsoft Power Apps et Microsoft Flow qui prennent actuellement en charge OpenAPI version 2.0. Pour choisir le format 2.0, définissez la propriété SerializeAsV2 dans Program.cs :

app.UseSwagger(options =>
{
    options.SerializeAsV2 = true;
});

Personnaliser et étendre

Swagger fournit des options pour documenter le modèle objet et personnaliser l’interface utilisateur en fonction de votre thème.

Informations sur l’API et description

L’action de configuration transmise à la méthode AddSwaggerGen ajoute des informations comme l’auteur, la license et la description.

Dans Program.cs, importez l’espace de noms suivant pour utiliser la classe OpenApiInfo :

using Microsoft.OpenApi.Models;

En utilisant la classe OpenApiInfo, modifiez les informations affichées dans l’interface utilisateur :

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "An ASP.NET Core Web API for managing ToDo items",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Example Contact",
            Url = new Uri("https://example.com/contact")
        },
        License = new OpenApiLicense
        {
            Name = "Example License",
            Url = new Uri("https://example.com/license")
        }
    });
});

L’IU Swagger affiche les informations de la version :

Interface utilisateur de Swagger avec les informations de version : description, auteur et licence.

Commentaires XML

Vous pouvez activer les commentaires XML en adoptant l’une des approches suivantes :

  • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Edit <project_name>.csproj.
  • Ajoutez GenerateDocumentationFile au fichier .csproj :
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

L’activation de commentaires XML fournit des informations de débogage sur les membres et types publics non documentés. Les membres et types non documentés sont indiqués par le message d’avertissement. Par exemple, le message suivant indique une violation du code d’avertissement 1591 :

warning CS1591: Missing XML comment for publicly visible type or member 'TodoController'

Pour supprimer des avertissements à l’échelle d’un projet, définissez une liste séparée par des points-virgules de codes d’avertissement à ignorer dans le fichier de projet. L’ajout des codes d’avertissement à $(NoWarn); applique aussi les valeurs par défaut C#.

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Pour supprimer des avertissements uniquement pour des membres spécifiques, placez le code dans les directives de préprocesseur #pragma warning. Cette approche est utile pour le code qui ne doit pas être exposé via la documentation de l’API. Dans l’exemple suivant, le code d’avertissement CS1591 est ignoré pour l’ensemble de la classe TodoContext. La mise en œuvre de code d’avertissement est restaurée à la fin de la définition de classe. Spécifier plusieurs codes d’avertissement avec une liste délimitée par des virgules.

namespace SwashbuckleSample.Models;

#pragma warning disable CS1591
public class TodoContext : DbContext
{
    public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }

    public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}
#pragma warning restore CS1591

Configurez Swagger de façon à utiliser le fichier XML généré avec les instructions précédentes. Pour les systèmes d’exploitation Linux ou non-Windows, les chemins et les noms de fichiers peuvent respecter la casse. Par exemple, un fichier TodoApi.XML est valide sur Windows, mais pas sur Ubuntu.

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "An ASP.NET Core Web API for managing ToDo items",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Example Contact",
            Url = new Uri("https://example.com/contact")
        },
        License = new OpenApiLicense
        {
            Name = "Example License",
            Url = new Uri("https://example.com/license")
        }
    });

    // using System.Reflection;
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});

Dans le code précédent, la réflexion est utilisée pour générer un nom de fichier XML correspondant à celui du projet d’API web. La propriété AppContext.BaseDirectory est utilisée pour construire le chemin du fichier XML. Certaines fonctionnalités de Swagger (par exemple, les schémas de paramètres d’entrée ou les méthodes HTTP et les codes de réponse issus des attributs respectifs) fonctionnent sans fichier de documentation XML. Pour la plupart des fonctionnalités cependant, à savoir les résumés de méthode et les descriptions des paramètres et des codes de réponse, l’utilisation d’un fichier XML est obligatoire.

Quand vous ajoutez des commentaires précédés de trois barres obliques à une action, Swagger UI ajoute la description à l’en-tête de la section. Ajoutez un élément <summary> au-dessus de l’action Delete :

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(long id)
{
    var item = await _context.TodoItems.FindAsync(id);

    if (item is null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(item);
    await _context.SaveChangesAsync();

    return NoContent();
}

L’IU Swagger affiche le texte interne de l’élément <summary> du code précédent :

Interface utilisateur de Swagger présentant le commentaire XML « Deletes a specific TodoItem. » pour la méthode DELETE.

L’interface utilisateur est définie par le schéma JSON généré :

"delete": {
    "tags": [
        "Todo"
    ],
    "summary": "Deletes a specific TodoItem.",
    "parameters": [
        {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "schema": {
                "type": "integer",
                "format": "int64"
            }
        }
    ],
    "responses": {
        "200": {
            "description": "Success"
        }
    }
},

Ajoutez un élément <remarks> à la documentation de la méthode de l’action Create. Il complète les informations spécifiées dans l’élément <summary> et fournit une interface utilisateur Swagger plus robuste. Le contenu de l’élément <remarks> peut être du texte, du code JSON ou du code XML.

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

Notez les améliorations de l’IU avec ces commentaires supplémentaires :

Interface utilisateur de Swagger avec des commentaires supplémentaires affichés.

Annotations de données

Marquez le modèle avec des attributs, qui se trouvent dans l’espace de noms System.ComponentModel.DataAnnotations, pour piloter les composants de l’interface utilisateur de Swagger.

Ajoutez l’attribut [Required] à la propriété Name de la classe TodoItem :

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace SwashbuckleSample.Models;

public class TodoItem
{
    public long Id { get; set; }

    [Required]
    public string Name { get; set; } = null!;

    [DefaultValue(false)]
    public bool IsComplete { get; set; }
}

La présence de cet attribut change le comportement de l’interface utilisateur et modifie le schéma JSON sous-jacent :

"schemas": {
    "TodoItem": {
        "required": [
            "name"
        ],
        "type": "object",
        "properties": {
            "id": {
                "type": "integer",
                "format": "int64"
            },
            "name": {
                "type": "string"
            },
            "isComplete": {
                "type": "boolean",
                "default": false
            }
        },
        "additionalProperties": false
    }
},

Ajoutez l’attribut [Produces("application/json")] au contrôleur d’API. Son objectif est de déclarer que les actions du contrôleur prennent en charge une réponse dont le type de contenu est application/json :

[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoController : ControllerBase
{

La liste déroulante Media type permet de sélectionner ce type de contenu comme valeur par défaut pour les actions GET du contrôleur :

Interface utilisateur de Swagger avec le type de contenu de réponse par défaut

À mesure que l’utilisation des annotations de données dans l’API web augmente, l’interface utilisateur et les pages d’aide de l’API deviennent de plus en plus descriptives et utiles.

Décrire des types de réponse

Les développeurs consommant une API web s’intéressent surtout à ce qui est retourné, en particulier les types de réponse et les codes d’erreur (s’ils ne sont pas standard). Les types de réponse et les codes d’erreur sont décrits dans les commentaires XML et les annotations de données.

L’action Create retourne un code d’état HTTP 201 en cas de réussite. Un code d’état HTTP 400 est retourné quand le corps de la demande postée est null. Sans documentation appropriée dans l’interface utilisateur de Swagger, le consommateur n’a pas connaissance de ces résultats attendus. Pour résoudre ce problème, ajoutez les lignes en surbrillance de l’exemple suivant :

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

L’interface utilisateur de Swagger documente maintenant clairement les codes de réponse HTTP attendus :

Interface utilisateur de Swagger présentant la description de la classe de réponse POST « Returns the newly created Todo item » et « 400 - If the item is null » pour le code d’état et la raison sous Response Messages.

Les conventions peuvent être utilisées comme alternatives à la décoration explicites des actions individuelles avec [ProducesResponseType]. Pour plus d'informations, consultez Utiliser les conventions d’API web.

Pour prendre en charge la décoration [ProducesResponseType], le package Swashbuckle.AspNetCore.Annotations propose des extensions pour activer et enrichir les métadonnées de réponse, de schéma et de paramètre.

Personnaliser l’interface utilisateur

L’interface utilisateur par défaut est à la fois fonctionnelle et présentable. Toutefois, les pages de documentation d’API doivent représenter votre marque ou thème. La personnalisation des composants Swashbuckle nécessite d’ajouter les ressources qui traitent les fichiers statiques et de générer la structure de dossiers pour héberger ces fichiers.

Activez le middleware de fichiers statiques :

app.UseHttpsRedirection();
app.UseStaticFiles();
app.MapControllers();

Pour injecter des feuilles de style CSS supplémentaires, ajoutez-les au dossier wwwroot du projet et spécifiez le chemin relatif dans les options d’intergiciel :

if (app.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options => // UseSwaggerUI is called only in Development.
    {
        options.InjectStylesheet("/swagger-ui/custom.css");
    });
}

Ressources supplémentaires

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Swashbuckle repose sur trois composants principaux :

  • Swashbuckle.AspNetCore.Swagger : modèle objet Swagger et intergiciel (middleware) pour exposer des objets SwaggerDocument sous forme de points de terminaison JSON.

  • Swashbuckle.AspNetCore.SwaggerGen : générateur Swagger qui crée des objets SwaggerDocument directement à partir de vos routes, contrôleurs et modèles. Ce composant est généralement associé à l’intergiciel du point de terminaison Swagger pour exposer automatiquement un fichier JSON Swagger.

  • Swashbuckle.AspNetCore.SwaggerUI: version incorporée de l’outil IU Swagger. Il interprète le fichier JSON Swagger afin de créer une expérience enrichie et personnalisable permettant de décrire les fonctionnalités de l’API web. Il intègre des ateliers de test pour les méthodes publiques.

Installation de package

Vous pouvez ajouter Swashbuckle en adoptant l’une des approches suivantes :

  • À partir de la fenêtre Console du Gestionnaire de package :

    • Accédez à Affichage>Autres fenêtres>Console du Gestionnaire de package.

    • Accédez au répertoire où se trouve le fichier TodoApi.csproj.

    • Exécutez la commande suivante :

      Install-Package Swashbuckle.AspNetCore -Version 5.6.3
      
  • À partir de la boîte de dialogue Gérer les packages NuGet :

    • Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions>Gérer les packages NuGet.
    • Affectez la valeur « nuget.org » à Source du package.
    • Vérifiez que l’option « Inclure la version préliminaire » est activée
    • Entrez « Swashbuckle.AspNetCore » dans la zone de recherche.
    • Sélectionnez le package « Swashbuckle.AspNetCore » le plus récent sous l’onglet Parcourir et cliquez sur Installer.

Ajouter et configurer l’intergiciel (middleware) Swagger

Ajoutez le générateur Swagger à la collection de services dans la méthode Startup.ConfigureServices :

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddControllers();

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen();
}

Dans la méthode Startup.Configure, activez l’intergiciel pour traiter le document JSON généré et l’interface utilisateur Swagger :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.)
        app.UseSwaggerUI();
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Remarque

Swashbuckle s’appuie sur Microsoft.AspNetCore.Mvc.ApiExplorer du modèle MVC pour découvrir les routes et les points de terminaison. Si le projet appelle AddMvc, les routes et les points de terminaison sont découverts automatiquement. Lors de l’appel de AddMvcCore, la méthode AddApiExplorer doit être appelée explicitement. Pour plus d’informations, consultez Swashbuckle, ApiExplorer et Routage.

L’appel de méthode UseSwaggerUI précédent active une version incorporée de l’outil d’interface utilisateur Swagger en développement. Cela dépend de l’intergiciel de fichier statique. Si vous ciblez le .NET Framework ou .NET Core 1.x, ajoutez le package NuGet Microsoft.AspNetCore.StaticFiles au projet.

Lancez l’application et accédez à http://localhost:<port>/swagger/v1/swagger.json. Le document généré décrivant les points de terminaison s’affiche comme dans la spécification OpenAPI (openapi.json).

L’interface utilisateur Swagger se trouve à l’adresse http://localhost:<port>/swagger. Explorez l’API via l’interface utilisateur Swagger et incorporez-la dans d’autres programmes.

Conseil

Pour utiliser l’IU Swagger à la racine de l’application (http://localhost:<port>/), définissez la propriété RoutePrefix sur une chaîne vide :

// // UseSwaggerUI Protected by if (env.IsDevelopment())
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    c.RoutePrefix = string.Empty;
});

Si vous utilisez des répertoires avec IIS ou un proxy inverse, définissez le point de terminaison Swagger sur un chemin relatif avec le préfixe ./. Par exemple : ./swagger/v1/swagger.json. L’utilisation de /swagger/v1/swagger.json indique à l’application de rechercher le fichier JSON à la racine réelle de l’URL (plus le préfixe de la route s’il est utilisé). Par exemple, utilisez http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json au lieu de http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Remarque

Par défaut, Swashbuckle génère et expose Swagger JSON dans la version 3.0 de la spécification, officiellement appelée spécification OpenAPI. Pour prendre en charge la compatibilité descendante, vous pouvez choisir d’exposer JSON au format 2.0. Ce format 2.0 est important pour les intégrations telles que Microsoft Power Apps et Microsoft Flow qui prennent actuellement en charge OpenAPI version 2.0. Pour choisir le format 2.0, définissez la propriété SerializeAsV2 dans Startup.Configure :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger(c =>
        {
            c.SerializeAsV2 = true;
        });

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        // UseSwaggerUI is called only in Development.
        app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Personnaliser et étendre

Swagger fournit des options pour documenter le modèle objet et personnaliser l’interface utilisateur en fonction de votre thème.

Dans la classe Startup, ajoutez les espaces de noms suivants :

using System;
using System.Reflection;
using System.IO;

Informations sur l’API et description

L’action de configuration transmise à la méthode AddSwaggerGen ajoute des informations comme l’auteur, la license et la description :

Dans la classe Startup, importez l’espace de noms suivant pour utiliser la classe OpenApiInfo :

using Microsoft.OpenApi.Models;

En utilisant la classe OpenApiInfo, modifiez les informations affichées dans l’interface utilisateur :

// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "A simple example ASP.NET Core Web API",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = new Uri("https://twitter.com/spboyer"),
        },
        License = new OpenApiLicense
        {
            Name = "Use under LICX",
            Url = new Uri("https://example.com/license"),
        }
    });
});

L’IU Swagger affiche les informations de la version :

Interface utilisateur de Swagger avec les informations de version : description, auteur et lien pour en savoir plus.

Commentaires XML

Vous pouvez activer les commentaires XML en adoptant l’une des approches suivantes :

  • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Edit <project_name>.csproj.
  • Ajoutez manuellement les lignes en évidence au fichier .csproj :
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

L’activation de commentaires XML fournit des informations de débogage sur les membres et types publics non documentés. Les membres et types non documentés sont indiqués par le message d’avertissement. Par exemple, le message suivant indique une violation du code d’avertissement 1591 :

warning CS1591: Missing XML comment for publicly visible type or member 'TodoController.GetAll()'

Pour supprimer des avertissements à l’échelle d’un projet, définissez une liste séparée par des points-virgules de codes d’avertissement à ignorer dans le fichier de projet. L’ajout des codes d’avertissement à $(NoWarn); applique aussi les valeurs par défaut C#.

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Pour supprimer des avertissements uniquement pour des membres spécifiques, placez le code dans les directives de préprocesseur #pragma warning. Cette approche est utile pour le code qui ne doit pas être exposé via la documentation de l’API. Dans l’exemple suivant, le code d’avertissement CS1591 est ignoré pour l’ensemble de la classe Program. La mise en œuvre de code d’avertissement est restaurée à la fin de la définition de classe. Spécifier plusieurs codes d’avertissement avec une liste délimitée par des virgules.

namespace TodoApi
{
#pragma warning disable CS1591
    public class Program
    {
        public static void Main(string[] args) =>
            BuildWebHost(args).Run();

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
#pragma warning restore CS1591
}

Configurez Swagger de façon à utiliser le fichier XML généré avec les instructions précédentes. Pour les systèmes d’exploitation Linux ou non-Windows, les chemins et les noms de fichiers peuvent respecter la casse. Par exemple, un fichier TodoApi.XML est valide sur Windows, mais pas sur Ubuntu.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddControllers();

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo
        {
            Version = "v1",
            Title = "ToDo API",
            Description = "A simple example ASP.NET Core Web API",
            TermsOfService = new Uri("https://example.com/terms"),
            Contact = new OpenApiContact
            {
                Name = "Shayne Boyer",
                Email = string.Empty,
                Url = new Uri("https://twitter.com/spboyer"),
            },
            License = new OpenApiLicense
            {
                Name = "Use under LICX",
                Url = new Uri("https://example.com/license"),
            }
        });

        // Set the comments path for the Swagger JSON and UI.
        var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        c.IncludeXmlComments(xmlPath);
    });
}

Dans le code précédent, la réflexion est utilisée pour générer un nom de fichier XML correspondant à celui du projet d’API web. La propriété AppContext.BaseDirectory est utilisée pour construire le chemin du fichier XML. Certaines fonctionnalités de Swagger (par exemple, les schémas de paramètres d’entrée ou les méthodes HTTP et les codes de réponse issus des attributs respectifs) fonctionnent sans fichier de documentation XML. Pour la plupart des fonctionnalités cependant, à savoir les résumés de méthode et les descriptions des paramètres et des codes de réponse, l’utilisation d’un fichier XML est obligatoire.

Quand vous ajoutez des commentaires précédés de trois barres obliques à une action, Swagger UI ajoute la description à l’en-tête de la section. Ajoutez un élément <summary> au-dessus de l’action Delete :

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>        
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
    var todo = _context.TodoItems.Find(id);

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

    _context.TodoItems.Remove(todo);
    _context.SaveChanges();

    return NoContent();
}

L’IU Swagger affiche le texte interne de l’élément <summary> du code précédent :

Interface utilisateur de Swagger présentant le commentaire XML « Deletes a specific TodoItem. » pour la méthode DELETE.

L’interface utilisateur est définie par le schéma JSON généré :

"delete": {
    "tags": [
        "Todo"
    ],
    "summary": "Deletes a specific TodoItem.",
    "operationId": "ApiTodoByIdDelete",
    "consumes": [],
    "produces": [],
    "parameters": [
        {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "type": "integer",
            "format": "int64"
        }
    ],
    "responses": {
        "200": {
            "description": "Success"
        }
    }
}

Ajoutez un élément <remarks> à la documentation de la méthode de l’action Create. Il complète les informations spécifiées dans l’élément <summary> et fournit une interface utilisateur Swagger plus robuste. Le contenu de l’élément <remarks> peut être du texte, du code JSON ou du code XML.

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>            
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

Notez les améliorations de l’IU avec ces commentaires supplémentaires :

Interface utilisateur de Swagger avec des commentaires supplémentaires affichés.

Annotations de données

Marquez le modèle avec des attributs, qui se trouvent dans l’espace de noms System.ComponentModel.DataAnnotations, pour piloter les composants de l’interface utilisateur de Swagger.

Ajoutez l’attribut [Required] à la propriété Name de la classe TodoItem :

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }

        [Required]
        public string Name { get; set; }

        [DefaultValue(false)]
        public bool IsComplete { get; set; }
    }
}

La présence de cet attribut change le comportement de l’interface utilisateur et modifie le schéma JSON sous-jacent :

"definitions": {
    "TodoItem": {
        "required": [
            "name"
        ],
        "type": "object",
        "properties": {
            "id": {
                "format": "int64",
                "type": "integer"
            },
            "name": {
                "type": "string"
            },
            "isComplete": {
                "default": false,
                "type": "boolean"
            }
        }
    }
},

Ajoutez l’attribut [Produces("application/json")] au contrôleur d’API. Son objectif est de déclarer que les actions du contrôleur prennent en charge une réponse dont le type de contenu est application/json :

[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
    private readonly TodoContext _context;

La zone de liste déroulante Response Content Type permet de sélectionner ce type de contenu comme valeur par défaut pour les actions GET du contrôleur :

Interface utilisateur de Swagger avec le type de contenu de réponse par défaut.

À mesure que l’utilisation des annotations de données dans l’API web augmente, l’interface utilisateur et les pages d’aide de l’API deviennent de plus en plus descriptives et utiles.

Décrire des types de réponse

Les développeurs consommant une API web s’intéressent surtout à ce qui est retourné, en particulier les types de réponse et les codes d’erreur (s’ils ne sont pas standard). Les types de réponse et les codes d’erreur sont décrits dans les commentaires XML et les annotations de données.

L’action Create retourne un code d’état HTTP 201 en cas de réussite. Un code d’état HTTP 400 est retourné quand le corps de la demande postée est null. Sans documentation appropriée dans l’interface utilisateur de Swagger, le consommateur n’a pas connaissance de ces résultats attendus. Pour résoudre ce problème, ajoutez les lignes en surbrillance de l’exemple suivant :

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>            
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

L’interface utilisateur de Swagger documente maintenant clairement les codes de réponse HTTP attendus :

Interface utilisateur de Swagger présentant la description de la classe de réponse POST « Returns the newly created Todo item » et « 400 - If the item is null » pour le code d’état et la raison sous Response Messages.

Dans ASP.NET Core 2.2 ou une version ultérieure, les conventions peuvent être utilisées comme alternatives à la décoration explicites des actions individuelles avec [ProducesResponseType]. Pour plus d'informations, consultez Utiliser les conventions d’API web.

Pour prendre en charge la décoration [ProducesResponseType], le package Swashbuckle.AspNetCore.Annotations propose des extensions pour activer et enrichir les métadonnées de réponse, de schéma et de paramètre.

Personnaliser l’interface utilisateur

L’interface utilisateur par défaut est à la fois fonctionnelle et présentable. Toutefois, les pages de documentation d’API doivent représenter votre marque ou thème. La personnalisation des composants Swashbuckle nécessite d’ajouter les ressources qui traitent les fichiers statiques et de générer la structure de dossiers pour héberger ces fichiers.

Si vous ciblez le .NET Framework ou .NET Core 1.x, ajoutez le package NuGet Microsoft.AspNetCore.StaticFiles au projet :

<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />

Le package NuGet précédent est déjà installé si vous ciblez .NET Core 2.x et que vous utilisez le métapackage.

Activez le middleware de fichiers statiques :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();

    if (env.IsDevelopment())
    {
        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Pour injecter des feuilles de style CSS supplémentaires, ajoutez-les au dossier wwwroot du projet et spécifiez le chemin relatif dans les options d’intergiciel :

if (env.IsDevelopment())
{
    app.UseSwaggerUI(c =>
    {
        c.InjectStylesheet("/swagger-ui/custom.css");
    }
}

Ressources supplémentaires