From d87c50609ccc42630402e672fe2a11a0dedd6f9d Mon Sep 17 00:00:00 2001 From: Shayne Boyer Date: Fri, 26 Jun 2020 14:33:40 -0400 Subject: [PATCH] Swashbuckle update (#18974) * Update to current version * cleanup AddSwaggerGen snippets * moving OpenApiInfo to proper location * powerapps and flow version note 2.0 example * annotations update * annotations edit * edit pass * fix note * update line number Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> --- .../getting-started-with-swashbuckle.md | 59 ++++++++++--------- .../2.0/TodoApi.Swashbuckle/Startup2.cs | 5 +- .../2.1/TodoApi.Swashbuckle/Startup2.cs | 5 +- .../3.0/TodoApi.Swashbuckle/Startup2.cs | 5 +- .../3.0/TodoApi.Swashbuckle/Startup3.cs | 47 +++++++++++++++ 5 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup3.cs diff --git a/aspnetcore/tutorials/getting-started-with-swashbuckle.md b/aspnetcore/tutorials/getting-started-with-swashbuckle.md index 18de4402e99b..64982bdbb3e1 100644 --- a/aspnetcore/tutorials/getting-started-with-swashbuckle.md +++ b/aspnetcore/tutorials/getting-started-with-swashbuckle.md @@ -4,7 +4,7 @@ author: zuckerthoben description: Learn how to add Swashbuckle to your ASP.NET Core web API project to integrate the Swagger UI. ms.author: scaddie ms.custom: mvc -ms.date: 01/17/2020 +ms.date: 06/26/2020 no-loc: [Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR] uid: tutorials/get-started-with-swashbuckle --- @@ -34,7 +34,7 @@ Swashbuckle can be added with the following approaches: * Execute the following command: ```powershell - Install-Package Swashbuckle.AspNetCore -Version 5.0.0 + Install-Package Swashbuckle.AspNetCore -Version 5.5.0 ``` * From the **Manage NuGet Packages** dialog: @@ -57,7 +57,7 @@ Swashbuckle can be added with the following approaches: Run the following command from the **Integrated Terminal**: ```dotnetcli -dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.0.0 +dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.5.0 ``` ### [.NET Core CLI](#tab/netcore-cli) @@ -65,34 +65,30 @@ dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.0.0 Run the following command: ```dotnetcli -dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.0.0 +dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.5.0 ``` --- ## Add and configure Swagger middleware -In the `Startup` class, import the following namespace to use the `OpenApiInfo` class: - -[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_InfoClassNamespace)] - Add the Swagger generator to the services collection in the `Startup.ConfigureServices` method: ::: moniker range="<= aspnetcore-2.0" -[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=8-11)] +[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=8)] ::: moniker-end ::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2" -[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=9-12)] +[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=9)] ::: moniker-end ::: moniker range=">= aspnetcore-3.0" -[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=8-11)] +[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=8)] ::: moniker-end @@ -110,6 +106,9 @@ In the `Startup.Configure` method, enable the middleware for serving the generat ::: moniker-end +> [!NOTE] +> Swashbuckle relies on MVC's to discover the routes and endpoints. If the project calls , routes and endpoints are discovered automatically. When calling , the method must be explicitly called. For more information, see [Swashbuckle, ApiExplorer, and Routing](https://github.com/domaindrivendev/Swashbuckle.AspNetCore#swashbuckle-apiexplorer-and-routing). + The preceding `UseSwaggerUI` method call enables the [Static File Middleware](xref:fundamentals/static-files). If targeting .NET Framework or .NET Core 1.x, add the [Microsoft.AspNetCore.StaticFiles](https://www.nuget.org/packages/Microsoft.AspNetCore.StaticFiles/) NuGet package to the project. Launch the app, and navigate to `http://localhost:/swagger/v1/swagger.json`. The generated document describing the endpoints appears as shown in [Swagger specification (swagger.json)](xref:tutorials/web-api-help-pages-using-swagger#swagger-specification-swaggerjson). @@ -123,6 +122,11 @@ The Swagger UI can be found at `http://localhost:/swagger`. Explore the AP If using directories with IIS or a reverse proxy, set the Swagger endpoint to a relative path using the `./` prefix. For example, `./swagger/v1/swagger.json`. Using `/swagger/v1/swagger.json` instructs the app to look for the JSON file at the true root of the URL (plus the route prefix, if used). For example, use `http://localhost://swagger/v1/swagger.json` instead of `http://localhost:///swagger/v1/swagger.json`. +> [!NOTE] +> By default, Swashbuckle generates and exposes Swagger JSON in version 3.0 of the specification—officially called the OpenAPI Specification. To support backwards compatibility, you can opt into exposing JSON in the 2.0 format instead. This 2.0 format is important for integrations such as Microsoft Power Apps and Microsoft Flow that currently support OpenAPI version 2.0. To opt into the 2.0 format, set the `SerializeAsV2` property in `Startup.Configure`: +> +> [!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup3.cs?name=snippet_Configure&highlight=4-7)] + ## Customize and extend Swagger provides options for documenting the object model and customizing the UI to match your theme. @@ -139,6 +143,12 @@ using System.IO; The configuration action passed to the `AddSwaggerGen` method adds information such as the author, license, and description: +In the `Startup` class, import the following namespace to use the `OpenApiInfo` class: + +[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_InfoClassNamespace)] + +Using the `OpenApiInfo` class, modify the information displayed in the UI: + [!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup4.cs?name=snippet_AddSwaggerGen)] The Swagger UI displays the version's information: @@ -440,11 +450,13 @@ The Swagger UI now clearly documents the expected HTTP response codes: In ASP.NET Core 2.2 or later, conventions can be used as an alternative to explicitly decorating individual actions with `[ProducesResponseType]`. For more information, see . +To support the `[ProducesResponseType]` decoration, the [Swashbuckle.AspNetCore.Annotations](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#swashbuckleaspnetcoreannotations) package offers extensions to enable and enrich the response, schema, and parameter metadata. + ::: moniker-end ### Customize the UI -The stock UI is both functional and presentable. However, API documentation pages should represent your brand or theme. Branding the Swashbuckle components requires adding the resources to serve static files and building the folder structure to host those files. +The default UI is both functional and presentable. However, API documentation pages should represent your brand or theme. Branding the Swashbuckle components requires adding the resources to serve static files and building the folder structure to host those files. If targeting .NET Framework or .NET Core 1.x, add the [Microsoft.AspNetCore.StaticFiles](https://www.nuget.org/packages/Microsoft.AspNetCore.StaticFiles) NuGet package to the project: @@ -468,20 +480,11 @@ Enable Static File Middleware: ::: moniker-end -Acquire the contents of the *dist* folder from the [Swagger UI GitHub repository](https://github.com/swagger-api/swagger-ui/tree/master/dist). This folder contains the necessary assets for the Swagger UI page. - -Create a *wwwroot/swagger/ui* folder, and copy into it the contents of the *dist* folder. - -Create a *custom.css* file, in *wwwroot/swagger/ui*, with the following CSS to customize the page header: - -[!code-css[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/wwwroot/swagger/ui/custom.css)] - -Reference *custom.css* in the *index.html* file inside ui folder, after any other CSS files: - -[!code-html[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/wwwroot/swagger/ui/index.html?name=snippet_SwaggerUiCss&highlight=3)] +To inject additional CSS stylesheets, add them to the project's *wwwroot* folder and specify the relative path in the middleware options: -Browse to the *index.html* page at `http://localhost:/swagger/ui/index.html`. Enter `https://localhost:/swagger/v1/swagger.json` in the header's textbox, and click the **Explore** button. The resulting page looks as follows: - -![Swagger UI with custom header title](web-api-help-pages-using-swagger/_static/custom-header.png) - -There's much more you can do with the page. See the full capabilities for the UI resources at the [Swagger UI GitHub repository](https://github.com/swagger-api/swagger-ui). +```csharp +app.UseSwaggerUI(c => +{ + c.InjectStylesheet("/swagger-ui/custom.css"); +} +``` diff --git a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs index 2212b74ac312..f5f9002950bb 100644 --- a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs +++ b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs @@ -22,10 +22,7 @@ public void ConfigureServices(IServiceCollection services) services.AddMvc(); // Register the Swagger generator, defining 1 or more Swagger documents - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); - }); + services.AddSwaggerGen(); } #endregion diff --git a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs index 49d7e71cbcf3..646b8463aea7 100644 --- a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs +++ b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs @@ -18,10 +18,7 @@ public void ConfigureServices(IServiceCollection services) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // Register the Swagger generator, defining 1 or more Swagger documents - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); - }); + services.AddSwaggerGen(); } #endregion diff --git a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs index 6fcf34483a92..8606abf46ed9 100644 --- a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs +++ b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs @@ -16,10 +16,7 @@ public void ConfigureServices(IServiceCollection services) services.AddControllers(); // Register the Swagger generator, defining 1 or more Swagger documents - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); - }); + services.AddSwaggerGen(); } #endregion diff --git a/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup3.cs b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup3.cs new file mode 100644 index 000000000000..f96d6672776a --- /dev/null +++ b/aspnetcore/tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup3.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using TodoApi.Models; + +namespace TodoApi +{ + public class Startup2 + { + #region snippet_ConfigureServices + public void ConfigureServices(IServiceCollection services) + { + services.AddDbContext(opt => + opt.UseInMemoryDatabase("TodoList")); + services.AddControllers(); + + // Register the Swagger generator, defining 1 or more Swagger documents + services.AddSwaggerGen(); + } + #endregion + + #region snippet_Configure + public void Configure(IApplicationBuilder app) + { + // 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. + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); + }); + + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + #endregion + } +}