Share via


Erste Schritte mit Swashbuckle und ASP.NET Core

Swashbuckle besteht aus drei Hauptkomponenten:

  • Swashbuckle.AspNetCore.Swagger: ein Swagger-Objektmodell und eine Swagger-Middleware, um SwaggerDocument-Objekte als JSON-Endpunkte verfügbar zu machen.

  • Swashbuckle.AspNetCore.SwaggerGen: ein Swagger-Generator, der SwaggerDocument-Objekte direkt aus Routen, Controllern und Modellen erstellt. Dieser wird üblicherweise mit der Middleware für den Swagger-Endpunkt kombiniert, um Swagger-JSONs automatisch verfügbar zu machen.

  • Swashbuckle.AspNetCore.SwaggerUI: eine eingebettete Version des Swagger UI-Tools. Diese interpretiert JSON-Daten von Swagger zur Erstellung einer umfassenden und anpassbaren Benutzeroberfläche, auf der Web-API-Funktionen beschrieben werden. Es enthält integrierte Testumgebungen für die öffentlichen Methoden.

Paketinstallation

Swashbuckle kann mit folgenden Vorgehensweisen hinzugefügt werden:

  • Aus dem Fenster Paket-Manager-Konsole:

    • Navigieren Sie zu Ansicht>Weitere Fenster>Paket-Manager-Konsole.

    • Navigieren Sie zu dem Verzeichnis, in dem die .csproj gespeichert ist.

    • Führen Sie den folgenden Befehl aus:

      Install-Package Swashbuckle.AspNetCore -Version 6.6.1
      
  • Aus dem Dialogfeld NuGet-Pakete verwalten:

    • Klicken Sie mit der rechten Maustaste unter Projektmappen-Explorer>NuGet-Pakete verwalten auf Ihr Projekt.
    • Legen Sie die Paketquelle auf „nuget.org“ fest.
    • Stellen Sie sicher, dass die Option „Vorabversion einschließen“ aktiviert ist.
    • Geben Sie „Swashbuckle.AspNetCore“ in das Suchfeld ein.
    • Wählen Sie das aktuelle Paket „Swashbuckle.AspNetCore“ auf der Registerkarte Durchsuchen aus, und klicken Sie auf Installieren.

Hinzufügen und Konfigurieren von Swagger-Middleware

Fügen Sie den Swagger-Generator zur Sammlung „services“ in Program.cs hinzu:

builder.Services.AddControllers();

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

Der Aufruf von AddEndpointsApiExplorer im vorherigen Beispiel ist nur für minimale APIs erforderlich. Weitere Informationen finden Sie in diesem StackOverflow-Beitrag.

Aktivieren Sie die Middleware für das generierte JSON-Dokument und die Swagger-Benutzeroberfläche ebenfalls in Program.cs:

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

Der vorangehende Code fügt die Swagger-Middleware nur hinzu, wenn die aktuelle Umgebung als Entwicklungsumgebung festgelegt ist. Der Methodenaufruf UseSwaggerUI ermöglicht eine eingebettete Version des Swagger UI-Tools.

Starten Sie die App, und navigieren Sie zu https://localhost:<port>/swagger/v1/swagger.json. Das generierte Dokument mit der Beschreibung der Endpunkte wird entsprechend der OpenAPI-Spezifikation (openapi.json) angezeigt.

Die Swagger-Benutzeroberfläche ist unter https://localhost:<port>/swagger verfügbar. Mit der Swagger-Benutzeroberfläche können Sie die API kennenlernen und sie in andere Programme integrieren.

Tipp

Legen Sie für die Eigenschaft RoutePrefix eine leere Zeichenfolge fest, um die Swagger-Benutzeroberfläche im App-Stamm (https://localhost:<port>/) bereitzustellen:

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

Wenn Sie Verzeichnisse mit ISS oder einem Reverseproxy verwenden, legen Sie den Swagger-Endpunkt mit dem Präfix ./ auf einen relativen Pfad fest. Beispielsweise ./swagger/v1/swagger.json. /swagger/v1/swagger.json weist die App an, am ursprünglichen Stamm der URL nach einer JSON-Datei (und ggf. nach einem Routenpräfix) zu suchen. Verwenden Sie z. B. https://localhost:<port>/<route_prefix>/swagger/v1/swagger.json statt https://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Hinweis

Standardmäßig generiert Swashbuckle Swagger-JSON-Code in Version 3.0 der Spezifikation – offiziell als OpenAPI-Spezifikation bezeichnet. Um die Abwärtskompatibilität zu unterstützen, können Sie stattdessen JSON im 2.0-Format verfügbar machen. Dieses 2.0-Format ist wichtig für Integrationen wie Microsoft Power Apps und Microsoft Flow, die derzeit OpenAPI-Version 2.0 unterstützen. Um das 2.0-Format zu verwenden, legen Sie die SerializeAsV2-Eigenschaft in Program.cs fest:

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

Anpassen und Erweitern

Swagger stellt Optionen für das Dokumentieren des Objektmodells und das Anpassen der Benutzeroberfläche bereit, damit diese mit Ihrem Design übereinstimmt.

API-Informationen und -Beschreibung

Durch die an die AddSwaggerGen-Methode übergebene Konfigurationsaktion werden Informationen wie Autor, Lizenz und Beschreibung hinzugefügt.

Importieren Sie in Program.cs den folgenden Namespace, um die OpenApiInfo-Klasse verwenden zu können:

using Microsoft.OpenApi.Models;

Ändern Sie die in der Benutzeroberfläche angezeigten Informationen mithilfe der OpenApiInfo-Klasse:

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

Auf der Swagger-Benutzeroberfläche werden die Versionsinformationen angezeigt:

Swagger-Benutzeroberfläche mit Versionsinformationen: Beschreibung, Autor und Lizenz.

XML-Kommentare

XML-Kommentare können mithilfe der folgenden Ansätze aktiviert werden:

  • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Edit <project_name>.csproj aus.
  • Fügen Sie der -Datei GenerateDocumentationFile.csproj hinzu:
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

Das Aktivieren von XML-Kommentaren stellt Debuginformationen zu nicht-dokumentierten öffentlichen Typen und Members bereit. Auf nicht dokumentierte Typen und Member wird durch die Warnmeldung verwiesen. Die folgende Meldung macht z.B. durch den Warnungscode 1591 auf einen Verstoß aufmerksam:

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

Um Warnungen projektübergreifend zu unterdrücken, definieren Sie eine Liste der zu ignorierenden Warnungscodes (mit Semikolon als Trennzeichen). Das Anfügen von Warnungscodes an $(NoWarn); gilt auch für die C#-Standardwerte.

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

Um Warnungen nur für bestimmte Member zu unterdrücken, schließen Sie den Code in #pragma warning-Präprozessordirektiven ein. Dieser Ansatz eignet sich für Code, der nicht über die API-Dokumentation verfügbar gemacht werden soll. Im folgenden Beispiel wird der Warnungscode CS1591 für die gesamte Klasse TodoContext ignoriert. Das Erzwingen des Warnungscodes wird am Ende der Klassendefinition wiederhergestellt. Geben Sie mehrere Warnungscodes in einer kommagetrennten Liste an.

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

Konfigurieren Sie Swagger so, dass die XML-Datei verwendet wird, die nach Befolgen der vorherigen Anweisungen generiert wurde. Bei Linux oder anderen Betriebssystemen als Windows können bei Dateinamen und -pfaden Groß-/Kleinbuchstaben berücksichtigt werden. Die Datei TodoApi.XML ist beispielsweise unter Windows, nicht aber unter Ubuntu gültig.

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

Im vorangehenden Codeausschnitt wurde durch Reflektion ein XML-Dateiname erstellt, der dem Namen des Web-API-Projekts entspricht. Die AppContext.BaseDirectory-Eigenschaft wird verwendet, um einen Pfad zu der XML-Datei zu erstellen. Einige Swagger-Features (z.B. Schemas von Eingabeparametern oder HTTP-Methoden und Antwortcodes aus den jeweiligen Attributen) funktionieren ohne XML-Dokumentationsdatei. Für die meisten Funktionen, nämlich Methodenzusammenfassungen und Beschreibungen von Parametern und Antwortcodes, ist die Verwendung einer XML-Datei unerlässlich.

Das Hinzufügen von Kommentaren mit drei Schrägstrichen zu einer Aktion erweitert die Swagger-Benutzeroberfläche, indem die Beschreibung zum Header des Abschnitts hinzugefügt wird. Fügen Sie nun über der Delete-Aktion ein Element <summary> hinzu:

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

Auf der Swagger-Benutzeroberfläche wird der innere Text des <summary>-Elements angezeigt, das im letzten Codeausschnitt angegeben wurde:

Swagger-Benutzeroberfläche mit dem XML-Kommentar „Löscht ein bestimmtes TodoItem“ für die DELETE-Methode.

Die Benutzeroberfläche wird durch das generierte JSON-Schema gesteuert:

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

Fügen Sie der Dokumentation der Create-Aktionsmethode das Element <remarks> hinzu. Dieses ergänzt die Informationen, die im <summary>-Element angegeben wurden, und sorgt für eine robustere Swagger-Benutzeroberfläche. Das <remarks>-Element kann aus Text, JSON-Code oder XML-Code bestehen.

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

Durch die zusätzlichen Kommentare wird die Benutzeroberfläche wie unten gezeigt erweitert:

Swagger-Benutzeroberfläche mit zusätzlichen Kommentaren.

Datenanmerkungen

Markieren Sie das Modell mit Attributen, die sich im Namespace System.ComponentModel.DataAnnotations befinden, um die Swagger-UI-Komponenten zu steuern.

Fügen Sie das [Required]-Attribut der Name-Eigenschaft der TodoItem-Klasse hinzu:

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

Das Vorhandensein dieses Attributs ändert das Verhalten der Benutzeroberfläche und des zugrunde liegenden JSON-Schemas:

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

Fügen Sie das [Produces("application/json")]-Attribut zum API-Controller hinzu. Dadurch kann deklariert werden, dass die Aktionen des Controllers den Inhaltstyp application/json für Antworten unterstützen:

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

Im Dropdownmenü des Medientyp ist dieser Inhaltstyp als Standard für die GET-Aktionen des Controllers ausgewählt:

Swagger UI mit Standardinhaltstyp für die Antwort

Mit zunehmender Verwendung von Datenanmerkungen in der Web-API werden die UI- und API-Hilfeseiten beschreibender und nützlicher.

Beschreiben von Antworttypen

Entwickler, die eine Web-API nutzen, interessieren sich vor allem dafür, welche Antworttypen und Fehlercodes zurückgegeben werden (wenn diese nicht dem Standard entsprechen). Die Antworttypen und Fehlercodes sind in den XML-Kommentaren und Datenanmerkungen gekennzeichnet.

Die Aktion Create gibt bei einer erfolgreichen Anforderung den Statuscode „HTTP 201“ zurück. Der Statuscode „HTTP 400“ wird zurückgegeben, wenn der gesendete Anforderungstext NULL ist. Ohne richtige Dokumentation in der Swagger-Benutzeroberfläche fehlt dem Consumer das Wissen über diese erwarteten Ergebnisse. Sie können dieses Problem beheben, indem Sie die hervorgehobenen Zeilen im folgenden Beispiel hinzufügen:

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

Die Swagger-Benutzeroberfläche dokumentiert nun deutlich die erwarteten HTTP-Antwortcodes:

Swagger-Benutzeroberfläche, die die Klassenbeschreibung „Gibt das neu erstellte Todo-Element zurück“ nach der Antwort anzeigt sowie „400“ für den Statuscode und „Wenn das Element NULL ist“ als Grund unter den Antwortnachrichten.

Alternativ können Konventionen verwendet werden, um einzelne Aktionen explizit mit [ProducesResponseType] zu ergänzen. Weitere Informationen finden Sie unter Verwenden von Web-API-Konventionen.

Zur Unterstützung der [ProducesResponseType]-Ergänzung bietet das Swashbuckle.AspNetCore.Annotations-Paket Erweiterungen zum Aktivieren und Erweitern der Antwort-, Schema- und Parametermetadaten.

Anpassen der Benutzeroberfläche

Die Standardbenutzeroberfläche ist zwar funktionsfähig und visuell ansprechend, auf API-Dokumentationsseiten sollte jedoch Ihre Marke oder Ihr Design zu sehen sein. Für das Branding von Swashbuckle-Komponenten sind zusätzliche Ressourcen erforderlich, damit statische Dateien bereitgestellt werden können und sich die Ordnerstruktur zum Hosten dieser Dateien erstellt lässt.

Aktivieren von Middleware für statische Dateien:

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

Um zusätzliche CSS-Stylesheets hinzuzufügen, fügen Sie sie dem Ordner wwwroot des Projekts hinzu, und geben Sie den relativen Pfad in den Middlewareoptionen an:

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

Zusätzliche Ressourcen

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Es gibt drei Hauptkomponenten von Swashbuckle:

  • Swashbuckle.AspNetCore.Swagger: ein Swagger-Objektmodell und eine Swagger-Middleware, um SwaggerDocument-Objekte als JSON-Endpunkte verfügbar zu machen.

  • Swashbuckle.AspNetCore.SwaggerGen: ein Swagger-Generator, der SwaggerDocument-Objekte direkt aus Routen, Controllern und Modellen erstellt. Dieser wird üblicherweise mit der Middleware für den Swagger-Endpunkt kombiniert, um Swagger-JSONs automatisch verfügbar zu machen.

  • Swashbuckle.AspNetCore.SwaggerUI: eine eingebettete Version des Swagger UI-Tools. Diese interpretiert JSON-Daten von Swagger zur Erstellung einer umfassenden und anpassbaren Benutzeroberfläche, auf der Web-API-Funktionen beschrieben werden. Es enthält integrierte Testumgebungen für die öffentlichen Methoden.

Paketinstallation

Swashbuckle kann mit folgenden Vorgehensweisen hinzugefügt werden:

  • Aus dem Fenster Paket-Manager-Konsole:

    • Navigieren Sie zu Ansicht>Weitere Fenster>Paket-Manager-Konsole.

    • Navigieren Sie zu dem Verzeichnis, in dem die TodoApi.csproj gespeichert ist.

    • Führen Sie den folgenden Befehl aus:

      Install-Package Swashbuckle.AspNetCore -Version 5.6.3
      
  • Aus dem Dialogfeld NuGet-Pakete verwalten:

    • Klicken Sie mit der rechten Maustaste unter Projektmappen-Explorer>NuGet-Pakete verwalten auf Ihr Projekt.
    • Legen Sie die Paketquelle auf „nuget.org“ fest.
    • Stellen Sie sicher, dass die Option „Vorabversion einschließen“ aktiviert ist.
    • Geben Sie „Swashbuckle.AspNetCore“ in das Suchfeld ein.
    • Wählen Sie das aktuelle Paket „Swashbuckle.AspNetCore“ auf der Registerkarte Durchsuchen aus, und klicken Sie auf Installieren.

Hinzufügen und Konfigurieren von Swagger-Middleware

Fügen Sie den Swagger-Generator zu der services-Sammlung in der Startup.ConfigureServices-Methode hinzu:

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

Aktivieren Sie die Middleware in der Startup.Configure-Methode, um das generierte JSON-Dokument und die Swagger-Benutzeroberfläche bereitzustellen:

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

Hinweis

Swashbuckle basiert beim Ermitteln der Routen und Endpunkte auf dem Microsoft.AspNetCore.Mvc.ApiExplorer von MVC. Wenn das Projekt AddMvc aufruft, werden Routen und Endpunkte automatisch erkannt. Beim Aufruf von AddMvcCore muss die AddApiExplorer-Methode explizit aufgerufen werden. Weitere Informationen finden Sie unter Swashbuckle, ApiExplorer, and Routing (Swashbuckle, ApiExplorer und Routing).

In der Entwicklung ermöglicht der vorherige UseSwaggerUI-Methodenaufruf eine eingebettete Version des Swagger UI-Tools. Diese hängt von der Static File Middleware ab. Wenn .NET Framework oder .NET Core 1.x die Zielkomponente ist, müssen Sie Ihrem Projekt das NuGet-Paket Microsoft.AspNetCore.StaticFiles hinzufügen.

Starten Sie die App, und navigieren Sie zu http://localhost:<port>/swagger/v1/swagger.json. Das generierte Dokument mit der Beschreibung der Endpunkte wird entsprechend der OpenAPI-Spezifikation (openapi.json) angezeigt.

Die Swagger-Benutzeroberfläche ist unter http://localhost:<port>/swagger verfügbar. Mit der Swagger-Benutzeroberfläche können Sie die API kennenlernen und sie in andere Programme integrieren.

Tipp

Legen Sie für die Eigenschaft RoutePrefix eine leere Zeichenfolge fest, um die Swagger-Benutzeroberfläche im App-Stamm (http://localhost:<port>/) bereitzustellen:

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

Wenn Sie Verzeichnisse mit ISS oder einem Reverseproxy verwenden, legen Sie den Swagger-Endpunkt mit dem Präfix ./ auf einen relativen Pfad fest. Beispielsweise ./swagger/v1/swagger.json. /swagger/v1/swagger.json weist die App an, am ursprünglichen Stamm der URL nach einer JSON-Datei (und ggf. nach einem Routenpräfix) zu suchen. Verwenden Sie z. B. http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json statt http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.

Hinweis

Standardmäßig generiert Swashbuckle Swagger-JSON-Code in Version 3.0 der Spezifikation – offiziell als OpenAPI-Spezifikation bezeichnet. Um die Abwärtskompatibilität zu unterstützen, können Sie stattdessen JSON im 2.0-Format verfügbar machen. Dieses 2.0-Format ist wichtig für Integrationen wie Microsoft Power Apps und Microsoft Flow, die derzeit OpenAPI-Version 2.0 unterstützen. Um das 2.0-Format zu verwenden, legen Sie die SerializeAsV2-Eigenschaft in Startup.Configure fest:

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

Anpassen und Erweitern

Swagger stellt Optionen für das Dokumentieren des Objektmodells und das Anpassen der Benutzeroberfläche bereit, damit diese mit Ihrem Design übereinstimmt.

Fügen Sie in der Startup-Klasse die folgenden Namespaces hinzu:

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

API-Informationen und -Beschreibung

Durch die Konfigurationsaktion, die an die AddSwaggerGen-Methode übergeben wird, werden Informationen wie Autor, Lizenz und Beschreibung hinzugefügt:

Importieren Sie in der Startup-Klasse den folgenden Namespace zur Verwendung der OpenApiInfo-Klasse:

using Microsoft.OpenApi.Models;

Ändern Sie die in der Benutzeroberfläche angezeigten Informationen mithilfe der OpenApiInfo-Klasse:

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

Auf der Swagger-Benutzeroberfläche werden die Versionsinformationen angezeigt:

Swagger-Benutzeroberfläche mit Versionsinformationen: Beschreibung, Autor, Link „Mehr anzeigen“.

XML-Kommentare

XML-Kommentare können mithilfe der folgenden Ansätze aktiviert werden:

  • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Edit <project_name>.csproj aus.
  • Fügen Sie die hervorgehobenen Zeilen manuell der .csproj-Datei hinzu:
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Das Aktivieren von XML-Kommentaren stellt Debuginformationen zu nicht-dokumentierten öffentlichen Typen und Members bereit. Auf nicht dokumentierte Typen und Member wird durch die Warnmeldung verwiesen. Die folgende Meldung macht z.B. durch den Warnungscode 1591 auf einen Verstoß aufmerksam:

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

Um Warnungen projektübergreifend zu unterdrücken, definieren Sie eine Liste der zu ignorierenden Warnungscodes (mit Semikolon als Trennzeichen). Das Anfügen von Warnungscodes an $(NoWarn); gilt auch für die C#-Standardwerte.

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

Um Warnungen nur für bestimmte Member zu unterdrücken, schließen Sie den Code in #pragma warning-Präprozessordirektiven ein. Dieser Ansatz eignet sich für Code, der nicht über die API-Dokumentation verfügbar gemacht werden soll. Im folgenden Beispiel wird der Warnungscode CS1591 für die gesamte Klasse Program ignoriert. Das Erzwingen des Warnungscodes wird am Ende der Klassendefinition wiederhergestellt. Geben Sie mehrere Warnungscodes in einer kommagetrennten Liste an.

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
}

Konfigurieren Sie Swagger so, dass die XML-Datei verwendet wird, die nach Befolgen der vorherigen Anweisungen generiert wurde. Bei Linux oder anderen Betriebssystemen als Windows können bei Dateinamen und -pfaden Groß-/Kleinbuchstaben berücksichtigt werden. Die Datei TodoApi.XML ist beispielsweise unter Windows, nicht aber unter Ubuntu gültig.

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

Im vorangehenden Codeausschnitt wurde durch Reflektion ein XML-Dateiname erstellt, der dem Namen des Web-API-Projekts entspricht. Die AppContext.BaseDirectory-Eigenschaft wird verwendet, um einen Pfad zu der XML-Datei zu erstellen. Einige Swagger-Features (z.B. Schemas von Eingabeparametern oder HTTP-Methoden und Antwortcodes aus den jeweiligen Attributen) funktionieren ohne XML-Dokumentationsdatei. Für die meisten Funktionen, nämlich Methodenzusammenfassungen und Beschreibungen von Parametern und Antwortcodes, ist die Verwendung einer XML-Datei unerlässlich.

Das Hinzufügen von Kommentaren mit drei Schrägstrichen zu einer Aktion erweitert die Swagger-Benutzeroberfläche, indem die Beschreibung zum Header des Abschnitts hinzugefügt wird. Fügen Sie nun über der Delete-Aktion ein Element <summary> hinzu:

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

Auf der Swagger-Benutzeroberfläche wird der innere Text des <summary>-Elements angezeigt, das im letzten Codeausschnitt angegeben wurde:

Swagger-Benutzeroberfläche mit dem XML-Kommentar „Löscht ein bestimmtes TodoItem“ für die DELETE-Methode.

Die Benutzeroberfläche wird durch das generierte JSON-Schema gesteuert:

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

Fügen Sie der Dokumentation der Create-Aktionsmethode das Element <remarks> hinzu. Dieses ergänzt die Informationen, die im <summary>-Element angegeben wurden, und sorgt für eine robustere Swagger-Benutzeroberfläche. Das <remarks>-Element kann aus Text, JSON-Code oder XML-Code bestehen.

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

Durch die zusätzlichen Kommentare wird die Benutzeroberfläche wie unten gezeigt erweitert:

Swagger-Benutzeroberfläche mit zusätzlichen Kommentaren.

Datenanmerkungen

Markieren Sie das Modell mit Attributen, die sich im Namespace System.ComponentModel.DataAnnotations befinden, um die Swagger-UI-Komponenten zu steuern.

Fügen Sie das [Required]-Attribut der Name-Eigenschaft der TodoItem-Klasse hinzu:

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

Das Vorhandensein dieses Attributs ändert das Verhalten der Benutzeroberfläche und des zugrunde liegenden JSON-Schemas:

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

Fügen Sie das [Produces("application/json")]-Attribut zum API-Controller hinzu. Dadurch kann deklariert werden, dass die Aktionen des Controllers den Inhaltstyp application/json für Antworten unterstützen:

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

Im Dropdownmenü des Anforderungsinhaltstyps ist dieser Inhaltstyp als Standard für die GET-Aktionen des Controllers ausgewählt:

Swagger-Benutzeroberfläche mit Standardinhaltstyp für die Antwort.

Mit zunehmender Verwendung von Datenanmerkungen in der Web-API werden die UI- und API-Hilfeseiten beschreibender und nützlicher.

Beschreiben von Antworttypen

Entwickler, die eine Web-API nutzen, interessieren sich vor allem dafür, welche Antworttypen und Fehlercodes zurückgegeben werden (wenn diese nicht dem Standard entsprechen). Die Antworttypen und Fehlercodes sind in den XML-Kommentaren und Datenanmerkungen gekennzeichnet.

Die Aktion Create gibt bei einer erfolgreichen Anforderung den Statuscode „HTTP 201“ zurück. Der Statuscode „HTTP 400“ wird zurückgegeben, wenn der gesendete Anforderungstext NULL ist. Ohne richtige Dokumentation in der Swagger-Benutzeroberfläche fehlt dem Consumer das Wissen über diese erwarteten Ergebnisse. Sie können dieses Problem beheben, indem Sie die hervorgehobenen Zeilen im folgenden Beispiel hinzufügen:

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

Die Swagger-Benutzeroberfläche dokumentiert nun deutlich die erwarteten HTTP-Antwortcodes:

Swagger-Benutzeroberfläche, die die Klassenbeschreibung „Gibt das neu erstellte Todo-Element zurück“ nach der Antwort anzeigt sowie „400“ für den Statuscode und „Wenn das Element NULL ist“ als Grund unter den Antwortnachrichten.

In ASP.NET Core 2.2 oder höher können Konventionen als Alternative verwendet werden, um einzelne Aktionen explizit mit [ProducesResponseType] zu ergänzen. Weitere Informationen finden Sie unter Verwenden von Web-API-Konventionen.

Zur Unterstützung der [ProducesResponseType]-Ergänzung bietet das Swashbuckle.AspNetCore.Annotations-Paket Erweiterungen zum Aktivieren und Erweitern der Antwort-, Schema- und Parametermetadaten.

Anpassen der Benutzeroberfläche

Die Standardbenutzeroberfläche ist zwar funktionsfähig und visuell ansprechend, auf API-Dokumentationsseiten sollte jedoch Ihre Marke oder Ihr Design zu sehen sein. Für das Branding von Swashbuckle-Komponenten sind zusätzliche Ressourcen erforderlich, damit statische Dateien bereitgestellt werden können und sich die Ordnerstruktur zum Hosten dieser Dateien erstellt lässt.

Wenn .NET Framework oder .NET Core 1.x die Zielkomponente ist, müssen Sie Ihrem Projekt das NuGet-Paket Microsoft.AspNetCore.StaticFiles hinzufügen:

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

Dieses Paket ist bereits installiert, wenn Sie als Zielkomponente .NET Core 2.x und das Metapaket verwenden.

Aktivieren von Middleware für statische Dateien:

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

Um zusätzliche CSS-Stylesheets hinzuzufügen, fügen Sie sie dem Ordner wwwroot des Projekts hinzu, und geben Sie den relativen Pfad in den Middlewareoptionen an:

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

Zusätzliche Ressourcen