Condividi tramite


Introduzione a Swashbuckle e ad ASP.NET Core

Nota

Swashbuckle non è disponibile in .NET 9 e versioni successive. Per un'alternativa, vedere Panoramica del supporto openAPI nelle app per le API principali di ASP.NET.

Esistono tre componenti principali di Swashbuckle:

  • Swashbuckle.AspNetCore.Swagger: un modello a oggetti Swagger e il middleware per esporre oggetti SwaggerDocument come endpoint JSON.

  • Swashbuckle.AspNetCore.SwaggerGen: un generatore Swagger che compila oggetti SwaggerDocument direttamente da route, controller e modelli. È usato in genere con il middleware di endpoint di Swagger per esporre automaticamente i file JSON di Swagger.

  • Swashbuckle.AspNetCore.SwaggerUI: una versione incorporata dello strumento interfaccia utente di Swagger, Interpreta i file JSON di Swagger per creare un'esperienza avanzata e personalizzabile per descrivere le funzionalità delle API Web. Include test harness predefiniti per i metodi pubblici.

Installazione del pacchetto

È possibile aggiungere Swashbuckle con gli approcci seguenti:

  • Dalla finestra Console di Gestione pacchetti:

    • Passare a Vista>Altre finestre>Console di Gestione pacchetti

    • Passare alla directory in cui esiste il .csproj file

    • Eseguire il comando seguente:

      Install-Package Swashbuckle.AspNetCore -Version 6.6.2
      
  • Dalla finestra di dialogo Gestisci pacchetti NuGet:

    • Fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni>Gestisci pacchetti NuGet
    • Impostare Origine pacchetto su "nuget.org"
    • Verificare che l'opzione "Includi versione preliminare" sia abilitata
    • Immettere "Swashbuckle.AspNetCore" nella casella di ricerca
    • Selezionare il pacchetto "Swashbuckle.AspNetCore" più recente nella scheda Sfoglia e fare clic su Installa

Aggiungere e configurare il middleware di Swagger

Aggiungere il generatore Swagger alla raccolta di servizi in Program.cs:

builder.Services.AddControllers();

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

La chiamata a AddEndpointsApiExplorer illustrata nell'esempio precedente è necessaria solo per le API minime. Per altre informazioni, vedere questo post di StackOverflow.

Abilitare il middleware per la gestione del documento JSON generato e dell'interfaccia utente di Swagger, anche in Program.cs:

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

Il codice precedente aggiunge il middleware Swagger solo se l'ambiente corrente è impostato su Sviluppo. La UseSwaggerUI chiamata al metodo abilita una versione incorporata dello strumento dell'interfaccia utente di Swagger.

Avviare l'app e passare a https://localhost:<port>/swagger/v1/swagger.json. Il documento generato che descrive gli endpoint viene visualizzato come illustrato nella specifica OpenAPI (openapi.json).

L'interfaccia utente di Swagger è disponibile in https://localhost:<port>/swagger. Esplorare l'API tramite l'interfaccia utente di Swagger e incorporarla in altri programmi.

Suggerimento

Per gestire l'interfaccia utente di Swagger nella radice dell'app (https://localhost:<port>/), impostare la proprietà RoutePrefix su una stringa vuota:

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

Se si usano le directory con ISS o il proxy inverso, impostare l'endpoint Swagger su un percorso relativo tramite il prefisso ./. Ad esempio: ./swagger/v1/swagger.json. L'uso di /swagger/v1/swagger.json indica all'app di cercare il file JSON nella vera radice dell'URL (con il prefisso della route, se usato). Usare, ad esempio, https://localhost:<port>/<route_prefix>/swagger/v1/swagger.json invece di https://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Nota

Per impostazione predefinita, Swashbuckle genera ed espone Swagger JSON nella versione 3.0 della specifica, denominata ufficialmente OpenAPI Specification. Per supportare la compatibilità con le versioni precedenti, è possibile acconsentire esplicitamente all'esposizione di JSON nel formato 2.0. Questo formato 2.0 è importante per le integrazioni, ad esempio Microsoft Power Apps e Microsoft Flow che attualmente supportano OpenAPI versione 2.0. Per acconsentire esplicitamente al formato 2.0, impostare la SerializeAsV2 proprietà in Program.cs:

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

Personalizzare ed estendere

Swagger offre opzioni per documentare il modello a oggetti e personalizzare l'interfaccia utente in modo che corrisponda al tema.

Informazioni e descrizione API

L'azione di configurazione passata al AddSwaggerGen metodo aggiunge informazioni quali l'autore, la licenza e la descrizione.

In Program.csimportare lo spazio dei nomi seguente per usare la OpenApiInfo classe :

using Microsoft.OpenApi.Models;

Usando la OpenApiInfo classe , modificare le informazioni visualizzate nell'interfaccia utente:

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'interfaccia utente di Swagger visualizza le informazioni sulla versione:

Interfaccia utente di Swagger con informazioni sulla versione: descrizione, autore e licenza.

Commenti in XML

I commenti XML possono essere abilitati con gli approcci seguenti:

  • Fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Edit <project_name>.csproj.
  • Aggiungere GenerateDocumentationFile al .csproj file:
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

Abilitando i commenti XML, viene eseguito il debug delle informazioni per membri e tipi pubblici non documentati. I membri e tipi non documentati sono indicati nel messaggio di avviso. Ad esempio, il messaggio seguente indica una violazione del codice di avviso 1591:

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

Per eliminare gli avvisi per l'intero progetto, definire un elenco delimitato da punto e virgola di codici di avviso da ignorare nel file di progetto. L'aggiunta di codici di avviso a $(NoWarn); applica anche i valori predefiniti di C#.

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

Per eliminare gli avvisi solo per membri specifici, racchiudere il codice in direttive del preprocessore #pragma warning. Questo approccio è utile per il codice che non deve essere esposto tramite la documentazione dell'API. Nell'esempio seguente il codice di avviso CS1591 viene ignorato per l'intera TodoContext classe. L'imposizione del codice di avviso viene ripristinata alla chiusura della definizione della classe. Specificare più codici di avviso con un elenco delimitato da virgole.

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

Configurare Swagger per usare il file XML che viene generato con le istruzioni precedenti. Per Linux o sistemi operativi diversi da Windows, i percorsi e i nomi di file possono fare distinzione tra maiuscole e minuscole. Ad esempio, un TodoApi.XML file è valido in Windows ma non in 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));
});

Nel codice precedente la reflection consente di compilare un nome file XML che corrisponde a quello del progetto API Web. La proprietà AppContext.BaseDirectory viene usata per costruire un percorso del file XML. Alcune funzionalità di Swagger (ad esempio, schemi di parametri di input o i metodi HTTP e i codici di risposta dai rispettivi attributi) funzionano senza l'uso di un file di documentazione XML. Per la maggior parte delle funzionalità, vale a dire i riepiloghi dei metodi e le descrizioni dei parametri e dei codici di risposta, l'uso di un file XML è obbligatorio.

Se si aggiungono commenti con barra tripla a un'azione si migliora Swagger UI aggiungendo la descrizione all'intestazione della sezione. Aggiungere un <elemento di riepilogo> sopra l'azione 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'interfaccia utente di Swagger visualizza il testo interno dell'elemento <summary> del codice precedente:

Interfaccia utente di Swagger che mostra il commento XML 'Elimina un TodoItem specifico'. Per il metodo DELETE.

L'interfaccia utente è determinata dallo schema JSON generato:

"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"
        }
    }
},

Aggiungere un <elemento osservazioni> alla documentazione del Create metodo di azione. In questo modo vengono integrate le informazioni specificate nell'elemento <summary> e l'interfaccia utente di Swagger risulta più affidabile. Il contenuto dell'elemento <remarks> può essere costituito da testo, JSON o 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);
}

Si notino i miglioramenti dell'interfaccia utente con questi commenti aggiuntivi:

Interfaccia utente di Swagger con commenti aggiuntivi visualizzati.

Annotazioni dei dati

Contrassegnare il modello con gli attributi, disponibili nello spazio dei nomi, per facilitare l'unità dei componenti dell'interfaccia System.ComponentModel.DataAnnotations utente di Swagger.

Aggiungere l'attributo [Required] alla proprietà Name della 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 presenza di questo attributo modifica il comportamento dell'interfaccia utente e lo schema JSON sottostante:

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

Aggiungere l'attributo [Produces("application/json")] al controller API. Il suo scopo consiste nel dichiarare che le azioni del controller supportano un tipo di contenuto della risposta di application/json:

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

L'elenco a discesa Tipo di supporto seleziona questo tipo di contenuto come predefinito per le azioni GET del controller:

Interfaccia utente di Swagger con tipo di contenuto di risposta predefinito

Con l'aumento dell'uso delle annotazioni dei dati nell'API Web, le pagine della Guida dell'API e dell'interfaccia utente diventano più descrittive e utili.

Descrivere i tipi di risposta

Gli sviluppatori che usano un'API Web sono maggiormente interessati a ciò che viene restituito, in particolare ai tipi di risposta e ai codici di errore (se non standard). I tipi di risposta e i codici di errore vengono indicati nei commenti XML e nelle annotazioni dei dati.

L'azione Create restituisce un codice di stato HTTP 201 in caso di esito positivo. Quando il corpo della richiesta inviata è Null, viene restituito un codice di stato HTTP 400. Senza la documentazione appropriata nell'interfaccia utente di Swagger, il consumer non riconosce tali risultati previsti. Risolvere il problema aggiungendo le righe evidenziate nell'esempio seguente:

/// <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'interfaccia utente di Swagger ora documenta chiaramente i codici di risposta HTTP previsti:

Interfaccia utente di Swagger che mostra la descrizione della classe di risposta POST 'Restituisce l'elemento Todo appena creato' e '400 - Se l'elemento è null' per il codice di stato e il motivo in Messaggi di risposta.

Le convenzioni possono essere usate come alternativa per decorare in modo esplicito le singole azioni con [ProducesResponseType]. Per altre informazioni, vedere Usare le convenzioni dell'API Web.

Per supportare la [ProducesResponseType] decorazione, il pacchetto Swashbuckle.AspNetCore.Annotations offre estensioni per abilitare e arricchire la risposta, lo schema e i metadati dei parametri.

Personalizzare l'interfaccia utente

L'interfaccia utente predefinita è funzionale e presentabile. ma è necessario che le pagine della documentazione API rappresentino il proprio marchio o tema. Per personalizzare i componenti Swashbuckle è necessario aggiungere le risorse per gestire i file statici e quindi compilare la struttura di cartelle per ospitare i file.

Abilitare il middleware dei file statici:

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

Per inserire fogli di stile CSS aggiuntivi, aggiungerli alla cartella wwwroot del progetto e specificare il percorso relativo nelle opzioni middleware:

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

Risorse aggiuntive

Visualizzare o scaricare il codice di esempio (procedura per il download)

Esistono tre componenti principali di Swashbuckle:

  • Swashbuckle.AspNetCore.Swagger: un modello a oggetti Swagger e il middleware per esporre oggetti SwaggerDocument come endpoint JSON.

  • Swashbuckle.AspNetCore.SwaggerGen: un generatore Swagger che compila oggetti SwaggerDocument direttamente da route, controller e modelli. È usato in genere con il middleware di endpoint di Swagger per esporre automaticamente i file JSON di Swagger.

  • Swashbuckle.AspNetCore.SwaggerUI: una versione incorporata dello strumento interfaccia utente di Swagger, Interpreta i file JSON di Swagger per creare un'esperienza avanzata e personalizzabile per descrivere le funzionalità delle API Web. Include test harness predefiniti per i metodi pubblici.

Installazione del pacchetto

È possibile aggiungere Swashbuckle con gli approcci seguenti:

  • Dalla finestra Console di Gestione pacchetti:

    • Passare a Vista>Altre finestre>Console di Gestione pacchetti

    • Passare alla directory in cui esiste il TodoApi.csproj file

    • Eseguire il comando seguente:

      Install-Package Swashbuckle.AspNetCore -Version 5.6.3
      
  • Dalla finestra di dialogo Gestisci pacchetti NuGet:

    • Fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni>Gestisci pacchetti NuGet
    • Impostare Origine pacchetto su "nuget.org"
    • Verificare che l'opzione "Includi versione preliminare" sia abilitata
    • Immettere "Swashbuckle.AspNetCore" nella casella di ricerca
    • Selezionare il pacchetto "Swashbuckle.AspNetCore" più recente nella scheda Sfoglia e fare clic su Installa

Aggiungere e configurare il middleware di Swagger

Aggiungere il generatore di Swagger alla raccolta di servizi nel metodo 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();
}

Nel metodo Startup.Configure abilitare il middleware per la gestione del documento JSON generato e l'interfaccia utente di 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();
    });
}

Nota

Swashbuckle si basa su MVC Microsoft.AspNetCore.Mvc.ApiExplorer per individuare le route e gli endpoint. Se il progetto chiama AddMvc, le route e gli endpoint vengono individuati automaticamente. Quando si chiama AddMvcCore, il AddApiExplorer metodo deve essere chiamato in modo esplicito. Per altre informazioni, vedere Swashbuckle, ApiExplorer e Routing.

In fase di sviluppo, la chiamata al metodo precedente UseSwaggerUI abilita una versione incorporata dello strumento dell'interfaccia utente di Swagger. Questo dipende dal middleware dei file statici. Se si usa .NET Framework o .NET Core 1.x, aggiungere il pacchetto NuGet Microsoft.AspNetCore.StaticFiles al progetto.

Avviare l'app e passare a http://localhost:<port>/swagger/v1/swagger.json. Il documento generato che descrive gli endpoint viene visualizzato come illustrato nella specifica OpenAPI (openapi.json).

L'interfaccia utente di Swagger è disponibile in http://localhost:<port>/swagger. Esplorare l'API tramite l'interfaccia utente di Swagger e incorporarla in altri programmi.

Suggerimento

Per gestire l'interfaccia utente di Swagger nella radice dell'app (http://localhost:<port>/), impostare la proprietà RoutePrefix su una stringa vuota:

// // 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;
});

Se si usano le directory con ISS o il proxy inverso, impostare l'endpoint Swagger su un percorso relativo tramite il prefisso ./. Ad esempio: ./swagger/v1/swagger.json. L'uso di /swagger/v1/swagger.json indica all'app di cercare il file JSON nella vera radice dell'URL (con il prefisso della route, se usato). Usare, ad esempio, http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json invece di http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Nota

Per impostazione predefinita, Swashbuckle genera ed espone Swagger JSON nella versione 3.0 della specifica, denominata ufficialmente OpenAPI Specification. Per supportare la compatibilità con le versioni precedenti, è possibile acconsentire esplicitamente all'esposizione di JSON nel formato 2.0. Questo formato 2.0 è importante per le integrazioni, ad esempio Microsoft Power Apps e Microsoft Flow che attualmente supportano OpenAPI versione 2.0. Per acconsentire esplicitamente al formato 2.0, impostare la SerializeAsV2 proprietà in 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();
    });
}

Personalizzare ed estendere

Swagger offre opzioni per documentare il modello a oggetti e personalizzare l'interfaccia utente in modo che corrisponda al tema.

Nella classe Startup aggiungere gli spazi dei nomi seguenti:

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

Informazioni e descrizione API

L'azione di configurazione passata al metodo AddSwaggerGen aggiunge informazioni come ad esempio autore, licenza e descrizione:

Nella classe Startup importare gli spazi dei nomi seguenti per usare la classe OpenApiInfo:

using Microsoft.OpenApi.Models;

Usando la OpenApiInfo classe , modificare le informazioni visualizzate nell'interfaccia utente:

// 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'interfaccia utente di Swagger visualizza le informazioni sulla versione:

Interfaccia utente di Swagger con informazioni sulla versione: descrizione, autore e altro collegamento.

Commenti in XML

I commenti XML possono essere abilitati con gli approcci seguenti:

  • Fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Edit <project_name>.csproj.
  • Aggiungere manualmente le righe evidenziate al .csproj file:
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Abilitando i commenti XML, viene eseguito il debug delle informazioni per membri e tipi pubblici non documentati. I membri e tipi non documentati sono indicati nel messaggio di avviso. Ad esempio, il messaggio seguente indica una violazione del codice di avviso 1591:

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

Per eliminare gli avvisi per l'intero progetto, definire un elenco delimitato da punto e virgola di codici di avviso da ignorare nel file di progetto. L'aggiunta di codici di avviso a $(NoWarn); applica anche i valori predefiniti di C#.

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

Per eliminare gli avvisi solo per membri specifici, racchiudere il codice in direttive del preprocessore #pragma warning. Questo approccio è utile per il codice che non deve essere esposto tramite la documentazione dell'API. Nell'esempio seguente il codice di avviso CS1591 viene ignorato per l'intera Program classe. L'imposizione del codice di avviso viene ripristinata alla chiusura della definizione della classe. Specificare più codici di avviso con un elenco delimitato da virgole.

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
}

Configurare Swagger per usare il file XML che viene generato con le istruzioni precedenti. Per Linux o sistemi operativi diversi da Windows, i percorsi e i nomi di file possono fare distinzione tra maiuscole e minuscole. Ad esempio, un TodoApi.XML file è valido in Windows ma non in 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);
    });
}

Nel codice precedente la reflection consente di compilare un nome file XML che corrisponde a quello del progetto API Web. La proprietà AppContext.BaseDirectory viene usata per costruire un percorso del file XML. Alcune funzionalità di Swagger (ad esempio, schemi di parametri di input o i metodi HTTP e i codici di risposta dai rispettivi attributi) funzionano senza l'uso di un file di documentazione XML. Per la maggior parte delle funzionalità, vale a dire i riepiloghi dei metodi e le descrizioni dei parametri e dei codici di risposta, l'uso di un file XML è obbligatorio.

Se si aggiungono commenti con barra tripla a un'azione si migliora Swagger UI aggiungendo la descrizione all'intestazione della sezione. Aggiungere un <elemento di riepilogo> sopra l'azione 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'interfaccia utente di Swagger visualizza il testo interno dell'elemento <summary> del codice precedente:

Interfaccia utente di Swagger che mostra il commento XML 'Elimina un TodoItem specifico'. Per il metodo DELETE.

L'interfaccia utente è determinata dallo schema JSON generato:

"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"
        }
    }
}

Aggiungere un <elemento osservazioni> alla documentazione del Create metodo di azione. In questo modo vengono integrate le informazioni specificate nell'elemento <summary> e l'interfaccia utente di Swagger risulta più affidabile. Il contenuto dell'elemento <remarks> può essere costituito da testo, JSON o 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);
}

Si notino i miglioramenti dell'interfaccia utente con questi commenti aggiuntivi:

Interfaccia utente di Swagger con commenti aggiuntivi visualizzati.

Annotazioni dei dati

Contrassegnare il modello con gli attributi, disponibili nello spazio dei nomi, per facilitare l'unità dei componenti dell'interfaccia System.ComponentModel.DataAnnotations utente di Swagger.

Aggiungere l'attributo [Required] alla proprietà Name della 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 presenza di questo attributo modifica il comportamento dell'interfaccia utente e lo schema JSON sottostante:

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

Aggiungere l'attributo [Produces("application/json")] al controller API. Il suo scopo consiste nel dichiarare che le azioni del controller supportano un tipo di contenuto della risposta di application/json:

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

L'elenco a discesa Response Content Type (Tipo di contenuto risposta) include questo tipo di contenuto come selezione predefinita per le azioni GET del controller:

Interfaccia utente di Swagger con tipo di contenuto della risposta predefinito.

Con l'aumento dell'uso delle annotazioni dei dati nell'API Web, le pagine della Guida dell'API e dell'interfaccia utente diventano più descrittive e utili.

Descrivere i tipi di risposta

Gli sviluppatori che usano un'API Web sono maggiormente interessati a ciò che viene restituito, in particolare ai tipi di risposta e ai codici di errore (se non standard). I tipi di risposta e i codici di errore vengono indicati nei commenti XML e nelle annotazioni dei dati.

L'azione Create restituisce un codice di stato HTTP 201 in caso di esito positivo. Quando il corpo della richiesta inviata è Null, viene restituito un codice di stato HTTP 400. Senza la documentazione appropriata nell'interfaccia utente di Swagger, il consumer non riconosce tali risultati previsti. Risolvere il problema aggiungendo le righe evidenziate nell'esempio seguente:

/// <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'interfaccia utente di Swagger ora documenta chiaramente i codici di risposta HTTP previsti:

Interfaccia utente di Swagger che mostra la descrizione della classe di risposta POST 'Restituisce l'elemento Todo appena creato' e '400 - Se l'elemento è null' per il codice di stato e il motivo in Messaggi di risposta.

In ASP.NET Core 2.2 o versioni successive, possono essere usate convenzioni in alternativa alla decorazione esplicita di azioni singole con [ProducesResponseType]. Per altre informazioni, vedere Usare le convenzioni dell'API Web.

Per supportare la [ProducesResponseType] decorazione, il pacchetto Swashbuckle.AspNetCore.Annotations offre estensioni per abilitare e arricchire la risposta, lo schema e i metadati dei parametri.

Personalizzare l'interfaccia utente

L'interfaccia utente predefinita è funzionale e presentabile. ma è necessario che le pagine della documentazione API rappresentino il proprio marchio o tema. Per personalizzare i componenti Swashbuckle è necessario aggiungere le risorse per gestire i file statici e quindi compilare la struttura di cartelle per ospitare i file.

Se si usa .NET Framework o .NET Core 1.x, aggiungere il pacchetto NuGet Microsoft.AspNetCore.StaticFiles al progetto:

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

Il pacchetto NuGet precedente è già installato se si usano .NET Core 2.x e il metapackage.

Abilitare il middleware dei file statici:

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();
    });
}

Per inserire fogli di stile CSS aggiuntivi, aggiungerli alla cartella wwwroot del progetto e specificare il percorso relativo nelle opzioni middleware:

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

Risorse aggiuntive