Swashbuckle 和 ASP.NET Core 入门Get started with Swashbuckle and ASP.NET Core

本文内容

作者:Shayne BoyerScott Addie

查看或下载示例代码如何下载

Swashbuckle 有三个主要组成部分:

  • Swashbuckle.AspNetCore.Swagger:将 SwaggerDocument 对象公开为 JSON 终结点的 Swagger 对象模型和中间件。

  • Swashbuckle.AspNetCore.SwaggerGen:从路由、控制器和模型直接生成 SwaggerDocument 对象的 Swagger 生成器。它通常与 Swagger 终结点中间件结合,以自动公开 Swagger JSON。

  • Swashbuckle.AspNetCore.SwaggerUI:Swagger UI 工具的嵌入式版本。它解释 Swagger JSON 以构建描述 Web API 功能的可自定义的丰富体验。它包括针对公共方法的内置测试工具。

包安装Package installation

可以使用以下方法来添加 Swashbuckle:

  • 从“程序包管理器控制台” 窗口:

    • 转到“视图” > “其他窗口” > “程序包管理器控制台”

    • 导航到包含 TodoApi.csproj 文件的目录

    • 请执行以下命令:

  1. Install-Package Swashbuckle.AspNetCore -Version 5.0.0
  • 从“管理 NuGet 程序包” 对话框中:

    • 右键单击“解决方案资源管理器” > “管理 NuGet 包”中的项目
    • 将“包源” 设置为“nuget.org”
    • 确保启用“包括预发行版”选项
    • 在搜索框中输入“Swashbuckle.AspNetCore”
    • 从“浏览” 选项卡中选择最新的“Swashbuckle.AspNetCore”包,然后单击“安装”
  • 右键单击“Solution Pad” > “添加包…” 中的“包” 文件夹
  • 将“添加包” 窗口的“源” 下拉列表设置为“nuget.org”
  • 确保启用“显示预发行包”选项
  • 在搜索框中输入“Swashbuckle.AspNetCore”
  • 从结果窗格中选择最新的“Swashbuckle.AspNetCore”包,然后单击“添加包”

从“集成终端” 中运行以下命令:

  1. dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.0.0

运行下面的命令:

  1. dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.0.0

添加并配置 Swagger 中间件Add and configure Swagger middleware

Startup 类中,导入以下命名空间来使用 OpenApiInfo 类:

  1. using Microsoft.OpenApi.Models;

将 Swagger 生成器添加到 Startup.ConfigureServices 方法中的服务集合中:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddMvc();
  6. // Register the Swagger generator, defining 1 or more Swagger documents
  7. services.AddSwaggerGen(c =>
  8. {
  9. c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
  10. });
  11. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddMvc()
  6. .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  7. // Register the Swagger generator, defining 1 or more Swagger documents
  8. services.AddSwaggerGen(c =>
  9. {
  10. c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
  11. });
  12. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddControllers();
  6. // Register the Swagger generator, defining 1 or more Swagger documents
  7. services.AddSwaggerGen(c =>
  8. {
  9. c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
  10. });
  11. }

Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务:

  1. public void Configure(IApplicationBuilder app)
  2. {
  3. // Enable middleware to serve generated Swagger as a JSON endpoint.
  4. app.UseSwagger();
  5. // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
  6. // specifying the Swagger JSON endpoint.
  7. app.UseSwaggerUI(c =>
  8. {
  9. c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
  10. });
  11. app.UseMvc();
  12. }
  1. public void Configure(IApplicationBuilder app)
  2. {
  3. // Enable middleware to serve generated Swagger as a JSON endpoint.
  4. app.UseSwagger();
  5. // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
  6. // specifying the Swagger JSON endpoint.
  7. app.UseSwaggerUI(c =>
  8. {
  9. c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
  10. });
  11. app.UseRouting();
  12. app.UseEndpoints(endpoints =>
  13. {
  14. endpoints.MapControllers();
  15. });
  16. }

前面的 UseSwaggerUI 方法调用启用了静态文件中间件如果以 .NET Framework 或 .NET Core 1.x 为目标,请将 Microsoft.AspNetCore.StaticFiles NuGet 包添加到项目。

启动应用,并导航到 http://localhost:<port>/swagger/v1/swagger.json生成的描述终结点的文档显示在 Swagger 规范 (swagger.json) 中。

可在 http://localhost:<port>/swagger 找到 Swagger UI。通过 Swagger UI 浏览 API,并将其合并其他计划中。

提示

要在应用的根 (http://localhost:<port>/) 处提供 Swagger UI,请将 RoutePrefix 属性设置为空字符串:

  1. app.UseSwaggerUI(c =>
  2. {
  3. c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
  4. c.RoutePrefix = string.Empty;
  5. });

如果使用目录及 IIS 或反向代理,请使用 ./ 前缀将 Swagger 终结点设置为相对路径。例如 ./swagger/v1/swagger.json使用 /swagger/v1/swagger.json 指示应用在 URL 的真实根目录中查找 JSON 文件(如果使用,加上路由前缀)。例如,请使用 http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json 而不是 http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json

自定义和扩展Customize and extend

Swagger 提供了为对象模型进行归档和自定义 UI 以匹配你的主题的选项。

Startup 类中,添加以下命名空间:

  1. using System;
  2. using System.Reflection;
  3. using System.IO;

API 信息和说明API info and description

传递给 AddSwaggerGen 方法的配置操作会添加诸如作者、许可证和说明的信息:

  1. // Register the Swagger generator, defining 1 or more Swagger documents
  2. services.AddSwaggerGen(c =>
  3. {
  4. c.SwaggerDoc("v1", new OpenApiInfo
  5. {
  6. Version = "v1",
  7. Title = "ToDo API",
  8. Description = "A simple example ASP.NET Core Web API",
  9. TermsOfService = new Uri("https://example.com/terms"),
  10. Contact = new OpenApiContact
  11. {
  12. Name = "Shayne Boyer",
  13. Email = string.Empty,
  14. Url = new Uri("https://twitter.com/spboyer"),
  15. },
  16. License = new OpenApiLicense
  17. {
  18. Name = "Use under LICX",
  19. Url = new Uri("https://example.com/license"),
  20. }
  21. });
  22. });

Swagger UI 显示版本的信息:

包含版本信息的 Swagger UI:说明、作者以及查看更多链接

XML 注释XML comments

可使用以下方法启用 XML 注释:

  • 在“解决方案资源管理器”中右键单击该项目,然后选择“编辑 .csproj” 。
  • 手动将突出显示的行添加到 .csproj 文件 :
  1. <PropertyGroup>
  2. <GenerateDocumentationFile>true</GenerateDocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>
  • 右键单击“解决方案资源管理器”中的项目,再选择“属性” 。
  • 选中“生成”选项卡的“输出”部分下的“XML 文档文件”框 。
  • 在 Solution Pad 中,按 control 并单击项目名称 。导航到“工具” > “编辑文件” 。
  • 手动将突出显示的行添加到 .csproj 文件 :
  1. <PropertyGroup>
  2. <GenerateDocumentationFile>true</GenerateDocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>
  • 打开“项目选项”对话框 >“生成”>“编译器”
  • 查看“常规选项”部分下的“生成 xml 文档”框

手动将突出显示的行添加到 .csproj 文件 :

  1. <PropertyGroup>
  2. <GenerateDocumentationFile>true</GenerateDocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>
  1. <PropertyGroup>
  2. <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>

手动将突出显示的行添加到 .csproj 文件 :

  1. <PropertyGroup>
  2. <GenerateDocumentationFile>true</GenerateDocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>
  1. <PropertyGroup>
  2. <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>

启用 XML 注释,为未记录的公共类型和成员提供调试信息。警告消息指示未记录的类型和成员。例如,以下消息指示违反警告代码 1591:

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

要在项目范围内取消警告,请定义要在项目文件中忽略的以分号分隔的警告代码列表。将警告代码追加到 $(NoWarn); 也会应用 C# 默认值

  1. <PropertyGroup>
  2. <GenerateDocumentationFile>true</GenerateDocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>
  1. <PropertyGroup>
  2. <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
  3. <NoWarn>$(NoWarn);1591</NoWarn>
  4. </PropertyGroup>

要仅针对特定成员取消警告,请将代码附入 #pragma warning 预处理程序指令中。此方法对于不应通过 API 文档公开的代码非常有用。在以下示例中,将忽略整个 Program 类的警告代码 CS1591。在类定义结束时还原警告代码的强制执行。使用逗号分隔的列表指定多个警告代码。

  1. namespace TodoApi
  2. {
  3. #pragma warning disable CS1591
  4. public class Program
  5. {
  6. public static void Main(string[] args) =>
  7. BuildWebHost(args).Run();
  8. public static IWebHost BuildWebHost(string[] args) =>
  9. WebHost.CreateDefaultBuilder(args)
  10. .UseStartup<Startup>()
  11. .Build();
  12. }
  13. #pragma warning restore CS1591
  14. }

将 Swagger 配置为使用按照上述说明生成的 XML 文件。对于 Linux 或非 Windows 操作系统,文件名和路径区分大小写。例如,“TodoApi.XML”文件在 Windows 上有效,但在 CentOS 上无效 。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddControllers();
  6. // Register the Swagger generator, defining 1 or more Swagger documents
  7. services.AddSwaggerGen(c =>
  8. {
  9. c.SwaggerDoc("v1", new OpenApiInfo
  10. {
  11. Version = "v1",
  12. Title = "ToDo API",
  13. Description = "A simple example ASP.NET Core Web API",
  14. TermsOfService = new Uri("https://example.com/terms"),
  15. Contact = new OpenApiContact
  16. {
  17. Name = "Shayne Boyer",
  18. Email = string.Empty,
  19. Url = new Uri("https://twitter.com/spboyer"),
  20. },
  21. License = new OpenApiLicense
  22. {
  23. Name = "Use under LICX",
  24. Url = new Uri("https://example.com/license"),
  25. }
  26. });
  27. // Set the comments path for the Swagger JSON and UI.
  28. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  29. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  30. c.IncludeXmlComments(xmlPath);
  31. });
  32. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddMvc()
  6. .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  7. // Register the Swagger generator, defining 1 or more Swagger documents
  8. services.AddSwaggerGen(c =>
  9. {
  10. c.SwaggerDoc("v1", new OpenApiInfo
  11. {
  12. Version = "v1",
  13. Title = "ToDo API",
  14. Description = "A simple example ASP.NET Core Web API",
  15. TermsOfService = new Uri("https://example.com/terms"),
  16. Contact = new OpenApiContact
  17. {
  18. Name = "Shayne Boyer",
  19. Email = string.Empty,
  20. Url = new Uri("https://twitter.com/spboyer"),
  21. },
  22. License = new OpenApiLicense
  23. {
  24. Name = "Use under LICX",
  25. Url = new Uri("https://example.com/license"),
  26. }
  27. });
  28. // Set the comments path for the Swagger JSON and UI.
  29. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  30. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  31. c.IncludeXmlComments(xmlPath);
  32. });
  33. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddMvc();
  6. // Register the Swagger generator, defining 1 or more Swagger documents
  7. services.AddSwaggerGen(c =>
  8. {
  9. c.SwaggerDoc("v1", new OpenApiInfo
  10. {
  11. Version = "v1",
  12. Title = "ToDo API",
  13. Description = "A simple example ASP.NET Core Web API",
  14. TermsOfService = new Uri("https://example.com/terms"),
  15. Contact = new OpenApiContact
  16. {
  17. Name = "Shayne Boyer",
  18. Email = string.Empty,
  19. Url = new Uri("https://twitter.com/spboyer"),
  20. },
  21. License = new OpenApiLicense
  22. {
  23. Name = "Use under LICX",
  24. Url = new Uri("https://example.com/license"),
  25. }
  26. });
  27. // Set the comments path for the Swagger JSON and UI.
  28. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  29. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  30. c.IncludeXmlComments(xmlPath);
  31. });
  32. }
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<TodoContext>(opt =>
  4. opt.UseInMemoryDatabase("TodoList"));
  5. services.AddMvc();
  6. // Register the Swagger generator, defining 1 or more Swagger documents
  7. services.AddSwaggerGen(c =>
  8. {
  9. c.SwaggerDoc("v1", new OpenApiInfo
  10. {
  11. Version = "v1",
  12. Title = "ToDo API",
  13. Description = "A simple example ASP.NET Core Web API",
  14. TermsOfService = new Uri("https://example.com/terms"),
  15. Contact = new OpenApiContact
  16. {
  17. Name = "Shayne Boyer",
  18. Email = string.Empty,
  19. Url = new Uri("https://twitter.com/spboyer"),
  20. },
  21. License = new OpenApiLicense
  22. {
  23. Name = "Use under LICX",
  24. Url = new Uri("https://example.com/license"),
  25. }
  26. });
  27. // Set the comments path for the Swagger JSON and UI.
  28. var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
  29. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  30. c.IncludeXmlComments(xmlPath);
  31. });
  32. }

在上述代码中,反射用于生成与 Web API 项目相匹配的 XML 文件名。AppContext.BaseDirectory属性用于构造 XML 文件的路径。一些 Swagger 功能(例如,输入参数的架构,或各自属性中的 HTTP 方法和响应代码)无需使用 XML 文档文件即可起作用。对于大多数功能(即方法摘要以及参数说明和响应代码说明),必须使用 XML 文件。

通过向节标题添加说明,将三斜杠注释添加到操作增强了 Swagger UI。执行 Delete 操作前添加 <summary> 元素:

  1. /// <summary>
  2. /// Deletes a specific TodoItem.
  3. /// </summary>
  4. /// <param name="id"></param>
  5. [HttpDelete("{id}")]
  6. public IActionResult Delete(long id)
  7. {
  8. var todo = _context.TodoItems.Find(id);
  9. if (todo == null)
  10. {
  11. return NotFound();
  12. }
  13. _context.TodoItems.Remove(todo);
  14. _context.SaveChanges();
  15. return NoContent();
  16. }

Swagger UI 显示上述代码的 <summary> 元素的内部文本:

显示 DELETE 方法的 XML 注释“删除特定 TodoItem”

生成的 JSON 架构驱动 UI:

  1. "delete": {
  2. "tags": [
  3. "Todo"
  4. ],
  5. "summary": "Deletes a specific TodoItem.",
  6. "operationId": "ApiTodoByIdDelete",
  7. "consumes": [],
  8. "produces": [],
  9. "parameters": [
  10. {
  11. "name": "id",
  12. "in": "path",
  13. "description": "",
  14. "required": true,
  15. "type": "integer",
  16. "format": "int64"
  17. }
  18. ],
  19. "responses": {
  20. "200": {
  21. "description": "Success"
  22. }
  23. }
  24. }

<remarks> 元素添加到 Create 操作方法文档。它可以补充 <summary> 元素中指定的信息,并提供更可靠的 Swagger UI。<remarks> 元素内容可包含文本、JSON 或 XML。

  1. /// <summary>
  2. /// Creates a TodoItem.
  3. /// </summary>
  4. /// <remarks>
  5. /// Sample request:
  6. ///
  7. /// POST /Todo
  8. /// {
  9. /// "id": 1,
  10. /// "name": "Item1",
  11. /// "isComplete": true
  12. /// }
  13. ///
  14. /// </remarks>
  15. /// <param name="item"></param>
  16. /// <returns>A newly created TodoItem</returns>
  17. /// <response code="201">Returns the newly created item</response>
  18. /// <response code="400">If the item is null</response>
  19. [HttpPost]
  20. [ProducesResponseType(typeof(TodoItem), StatusCodes.Status201Created)]
  21. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  22. public IActionResult Create([FromBody] TodoItem item)
  23. {
  24. if (item == null)
  25. {
  26. return BadRequest();
  27. }
  28. _context.TodoItems.Add(item);
  29. _context.SaveChanges();
  30. return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
  31. }
  1. /// <summary>
  2. /// Creates a TodoItem.
  3. /// </summary>
  4. /// <remarks>
  5. /// Sample request:
  6. ///
  7. /// POST /Todo
  8. /// {
  9. /// "id": 1,
  10. /// "name": "Item1",
  11. /// "isComplete": true
  12. /// }
  13. ///
  14. /// </remarks>
  15. /// <param name="item"></param>
  16. /// <returns>A newly created TodoItem</returns>
  17. /// <response code="201">Returns the newly created item</response>
  18. /// <response code="400">If the item is null</response>
  19. [HttpPost]
  20. [ProducesResponseType(StatusCodes.Status201Created)]
  21. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  22. public ActionResult<TodoItem> Create(TodoItem item)
  23. {
  24. _context.TodoItems.Add(item);
  25. _context.SaveChanges();
  26. return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
  27. }
  1. /// <summary>
  2. /// Creates a TodoItem.
  3. /// </summary>
  4. /// <remarks>
  5. /// Sample request:
  6. ///
  7. /// POST /Todo
  8. /// {
  9. /// "id": 1,
  10. /// "name": "Item1",
  11. /// "isComplete": true
  12. /// }
  13. ///
  14. /// </remarks>
  15. /// <param name="item"></param>
  16. /// <returns>A newly created TodoItem</returns>
  17. /// <response code="201">Returns the newly created item</response>
  18. /// <response code="400">If the item is null</response>
  19. [HttpPost]
  20. [ProducesResponseType(StatusCodes.Status201Created)]
  21. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  22. public ActionResult<TodoItem> Create(TodoItem item)
  23. {
  24. _context.TodoItems.Add(item);
  25. _context.SaveChanges();
  26. return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
  27. }

请注意带这些附加注释的 UI 增强功能:

显示包含其他注释的 Swagger UI

数据注释Data annotations

使用 System.ComponentModel.DataAnnotations 命名空间中的属性来标记模型,以帮助驱动 Swagger UI 组件。

[Required] 属性添加到 TodoItem 类的 Name 属性:

  1. using System.ComponentModel;
  2. using System.ComponentModel.DataAnnotations;
  3. namespace TodoApi.Models
  4. {
  5. public class TodoItem
  6. {
  7. public long Id { get; set; }
  8. [Required]
  9. public string Name { get; set; }
  10. [DefaultValue(false)]
  11. public bool IsComplete { get; set; }
  12. }
  13. }

此属性的状态更改 UI 行为并更改基础 JSON 架构:

  1. "definitions": {
  2. "TodoItem": {
  3. "required": [
  4. "name"
  5. ],
  6. "type": "object",
  7. "properties": {
  8. "id": {
  9. "format": "int64",
  10. "type": "integer"
  11. },
  12. "name": {
  13. "type": "string"
  14. },
  15. "isComplete": {
  16. "default": false,
  17. "type": "boolean"
  18. }
  19. }
  20. }
  21. },

[Produces("application/json")] 属性添加到 API 控制器。这样做的目的是声明控制器的操作支持 application/json 的响应内容类型 :

  1. [Produces("application/json")]
  2. [Route("api/[controller]")]
  3. public class TodoController : ControllerBase
  4. {
  5. private readonly TodoContext _context;
  1. [Produces("application/json")]
  2. [Route("api/[controller]")]
  3. [ApiController]
  4. public class TodoController : ControllerBase
  5. {
  6. private readonly TodoContext _context;
  1. [Produces("application/json")]
  2. [Route("api/[controller]")]
  3. [ApiController]
  4. public class TodoController : ControllerBase
  5. {
  6. private readonly TodoContext _context;

“响应内容类型” 下拉列表选此内容类型作为控制器的默认 GET 操作:

包含默认响应内容类型的 Swagger UI

随着 Web API 中的数据注释的使用越来越多,UI 和 API 帮助页变得更具说明性和更为有用。

描述响应类型Describe response types

使用 Web API 的开发人员最关心的问题是返回的内容,特别是响应类型和错误代码(如果不标准)。在 XML 注释和数据注释中表示响应类型和错误代码。

Create 操作成功后返回 HTTP 201 状态代码。发布的请求正文为 NULL 时,将返回 HTTP 400 状态代码。如果 Swagger UI 中没有提供合适的文档,那么使用者会缺少对这些预期结果的了解。在以下示例中,通过添加突出显示的行解决此问题:

  1. /// <summary>
  2. /// Creates a TodoItem.
  3. /// </summary>
  4. /// <remarks>
  5. /// Sample request:
  6. ///
  7. /// POST /Todo
  8. /// {
  9. /// "id": 1,
  10. /// "name": "Item1",
  11. /// "isComplete": true
  12. /// }
  13. ///
  14. /// </remarks>
  15. /// <param name="item"></param>
  16. /// <returns>A newly created TodoItem</returns>
  17. /// <response code="201">Returns the newly created item</response>
  18. /// <response code="400">If the item is null</response>
  19. [HttpPost]
  20. [ProducesResponseType(typeof(TodoItem), StatusCodes.Status201Created)]
  21. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  22. public IActionResult Create([FromBody] TodoItem item)
  23. {
  24. if (item == null)
  25. {
  26. return BadRequest();
  27. }
  28. _context.TodoItems.Add(item);
  29. _context.SaveChanges();
  30. return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
  31. }
  1. /// <summary>
  2. /// Creates a TodoItem.
  3. /// </summary>
  4. /// <remarks>
  5. /// Sample request:
  6. ///
  7. /// POST /Todo
  8. /// {
  9. /// "id": 1,
  10. /// "name": "Item1",
  11. /// "isComplete": true
  12. /// }
  13. ///
  14. /// </remarks>
  15. /// <param name="item"></param>
  16. /// <returns>A newly created TodoItem</returns>
  17. /// <response code="201">Returns the newly created item</response>
  18. /// <response code="400">If the item is null</response>
  19. [HttpPost]
  20. [ProducesResponseType(StatusCodes.Status201Created)]
  21. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  22. public ActionResult<TodoItem> Create(TodoItem item)
  23. {
  24. _context.TodoItems.Add(item);
  25. _context.SaveChanges();
  26. return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
  27. }
  1. /// <summary>
  2. /// Creates a TodoItem.
  3. /// </summary>
  4. /// <remarks>
  5. /// Sample request:
  6. ///
  7. /// POST /Todo
  8. /// {
  9. /// "id": 1,
  10. /// "name": "Item1",
  11. /// "isComplete": true
  12. /// }
  13. ///
  14. /// </remarks>
  15. /// <param name="item"></param>
  16. /// <returns>A newly created TodoItem</returns>
  17. /// <response code="201">Returns the newly created item</response>
  18. /// <response code="400">If the item is null</response>
  19. [HttpPost]
  20. [ProducesResponseType(StatusCodes.Status201Created)]
  21. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  22. public ActionResult<TodoItem> Create(TodoItem item)
  23. {
  24. _context.TodoItems.Add(item);
  25. _context.SaveChanges();
  26. return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
  27. }

Swagger UI 现在清楚地记录预期的 HTTP 响应代码:

Swagger UI 针对“响应消息”下的状态代码和原因显示 POST 响应类描述“返回新建的待办事项”和“400 - 如果该项为 null”

在 ASP.NET Core 2.2 或更高版本中,约定可以用作使用 [ProducesResponseType] 显式修饰各操作的替代方法。有关详细信息,请参阅 使用 Web API 约定

自定义 UICustomize the UI

股票 UI 既实用又可呈现。但是,API 文档页应代表品牌或主题。将 Swashbuckle 组件标记为需要添加资源以提供静态文件,并构建文件夹结构以托管这些文件。

如果以 .NET Framework 或 .NET Core 1.x 为目标,请将 Microsoft.AspNetCore.StaticFiles NuGet 包添加到项目:

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

如果以 .NET Core 2.x 为目标并使用元包,则已安装上述 NuGet 包。

启用静态文件中间件:

  1. public void Configure(IApplicationBuilder app)
  2. {
  3. app.UseStaticFiles();
  4. // Enable middleware to serve generated Swagger as a JSON endpoint.
  5. app.UseSwagger();
  6. // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
  7. // specifying the Swagger JSON endpoint.
  8. app.UseSwaggerUI(c =>
  9. {
  10. c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
  11. });
  12. app.UseMvc();
  13. }
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();

    // 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 =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

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

Swagger UI GitHub 存储库中获取 dist 文件夹的内容。此文件夹包含 Swagger UI 页必需的资产。

创建 wwwroot/swagger/ui 文件夹,然后将 dist 文件夹的内容复制到其中 。

使用以下 CSS 在 wwwroot/swagger/ui 中创建 custom.css 文件,以自定义页面标题 :

.swagger-ui .topbar {
    background-color: #000;
    border-bottom: 3px solid #547f00;
}

引用其他 CSS 文件后,引用“ui”文件夹内 index.html 文件中的 custom.css :

<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
<link rel="stylesheet" type="text/css" href="custom.css">

浏览到 http://localhost:<port>/swagger/ui/index.html 中的 index.html 页。在标题文本框中输入 https://localhost:<port>/swagger/v1/swagger.json,然后单击“浏览” 按钮。生成的页面如下所示:

使用自定义标题的 Swagger UI

还可以对页面执行更多操作。Swagger UI GitHub 存储库中查看 UI 资源的完整功能。