ASP.NET Core – Swagger OpenAPI (Swashbuckle)

前言

Swagger (OpenAPI) 是一套 Web API 文档规范. 

ASP.NET Core 有 2 个 Library 可用来实现 Swagger.

Swashbuckle 和 NSwag.

NSwag 能直接生成 client code 比如 JS, TypeScript 等等, 但 ASP.NET Core 默认的模板使用的是 Swashbuckle.

 

主要参考

Get started with Swashbuckle and ASP.NET Core

Controller action return types in ASP.NET Core web API

 

创建 Web API 模板

dotnet new webapi -o TestSwagger

ASP.NET Core 6.0 开始 Web API 模板自带了 Swagger. 所以不需要自己装 nuget

运行起来长这样 https://localhost:7055/swagger/index.html

 

配置 docs

services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1.0", new OpenApiInfo
    {
        Title = "Project Web API",
        Version = "v1.0",
        Description = "Project Web API version 1.0",
        Contact = new OpenApiContact
        {
            Name = "Derrick Yam",
            Email = "hengkeat87@gmail.com",
        },
    });
});

UI Endpoint

app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/swagger/v1.0/swagger.json", "Project Web API v1.0");
    options.DocExpansion(DocExpansion.None); // 默认是自动开, 我不喜欢, 所以关掉它
});

 

开启 XML comments

打开 project.csproj, 添加 2 行, Nowarn 是去掉警告, 不然会很吵.

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

添加

services.AddSwaggerGen(options =>
{
    ... 
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    options.IncludeXmlComments(xmlPath);
});

 

Controller > Action

Action 大概长这样

/// <summary>
/// some summary here...
/// </summary>
/// <remarks>
/// some remark here...
/// </remarks>
/// <param name="dto">Customer information</param>
/// <returns>A newly created customer</returns>
/// <response code="201">Returns the newly created customer</response>
/// <response code="400">When DTO invalid</response>   
[HttpPost("customers")]
[Consumes(MediaTypeNames.Application.Json)] // 接收 json
[Produces(MediaTypeNames.Application.Json)] // 返回 json
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(Customer))] // 有可能返回 200, 可以定义类型, 或者用 ActionResult 定义(那这里就不需要了)
[ProducesResponseType(StatusCodes.Status400BadRequest)] // 有可能返回 400
public async Task<ActionResult<Customer>> CreateCustomerAsync(
    [FromBody] CreateCustomerDTO dto
)
{
    ...
    return CreatedAtAction("GetById", new { customerId = customer.CustomerId }, customer);
}

关于 return type 可以看这篇, 这些注释最终就会出现在 docs 里.

ODataController action 长这样 (just example 不要管 versioning 哪些先)

[ApiController]
[ApiVersion("1.0")]
public class CustomersController : ODataController
{
    private readonly ApplicationDbContext _db;

    public CustomersController(
        ApplicationDbContext db
    )
    {
        _db = db;
    }

    [HttpGet("customers")]
    [Produces(MediaTypeNames.Application.Json)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [EnableQuery]
    public ActionResult<IEnumerable<Customer>> GetCustomers()
    {
        return Ok(_db.Customers);
    }

    [HttpGet("customers/{id}")]
    [Produces(MediaTypeNames.Application.Json)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [EnableQuery]
    public ActionResult<Customer> GetByIdAsync(int id)
    {
        return Ok(SingleResult.Create(_db.Customers.Where(c => c.CustomerId == id)));
    }
}
View Code
posted @ 2021-10-25 15:19  兴杰  阅读(124)  评论(0编辑  收藏  举报