Swagger在 NetCore中的使用

1,063 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

Swagger只是一个规范,不是一个实现!他的正式名称是OpenAPI

先把程序跑起来,直接上手

引入包:Swashbuckle.AspNetCore

在Startup.cs文件中配置并启动服务

在 ConfigureServices 类中配置服务(注入容器)

//引入 OpenApiInfo 的命名空间
using Microsoft.OpenApi.Models;

services.AddSwaggerGen(x =>
{
    x.SwaggerDoc("v1", new OpenApiInfo() { Title = "Web Api", Version = "v1" });
});

如果安装的 Swashbuckle.AspNetCore Nuget包版本<= 3.0.0,写法略有不同

services.AddSwaggerGen(x =>
{
    x.SwaggerDoc("v1", new Info() { Title = "Web Api", Version = "v1" });
});

将 OpenApiInfo 替换成 Info 即可      // 正式名称叫OpenAPI ....

在Configure 类中启动http中间件(响应请求)

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();//开发时可以直接暴露错误堆栈信息

    #region swagger
    app.UseSwagger();
    app.UseSwaggerUI(x =>
    {
        x.SwaggerEndpoint("/swagger/v1/swagger.json", "Web App V1");
    });
    #endregion
}

之所以写到这个if语句中,是因为Swagger文档只用于开发环境中,方便前后端人员交流使用,一旦项目处于生产阶段,这个文档也就废弃了。

启动项目

修改url,在端口号后面添加 /swagger ,然后 回车键 即可

OK,到这里,基本功能完成,可以使用了!

会用了还不够,要用好,丰富细节

丰富内容清单

  • 版本信息可以再详细点
  • api方法添加中文注释
  • 启动项目直接进入到 swagger 文档页面
  • Models添加 限制/注解 信息,让字段信息更丰富
  • .....

new OpenApiInfo()添加其他信息

查看源码看看有多少属性

namespace Microsoft.OpenApi.Models
{
    public class OpenApiInfo : Object, IOpenApiSerializable, IOpenApiElement, IOpenApiExtensible
    {
        public String Title
        
        public String Description
       
        public String Version
       
        public Uri TermsOfService
        
        public OpenApiContact Contact
       
        public OpenApiLicense License
        
        public IDictionary<String, IOpenApiExtension> Extensions

添加属性后代码:

services.AddSwaggerGen(x =>
{
    x.SwaggerDoc("v1", new OpenApiInfo()
    {
        Title = "Web Api",
        Version = "v1",
        Description = "Web Api 版本v1的描述信息",
        TermsOfService = new System.Uri("http://www.bilibili.com"), // 服务条款
        Contact = new OpenApiContact // 联系信息
        {
            Email = "123456@sina.com",
            Name = "张三",
            Url = new System.Uri("http://www.taobao.com")
        },
        License = new OpenApiLicense
        { 
            Name = "开放APi许可证",
         	Url = new Uri("http://www.sina.com")
         }
    });
});

UI效果:

api方法添加中文注释

给api方法或接口添加注释内容

在方法上一行连续按三次 / 即可 

在指定文件夹中生成 .xml 文档

  • 鼠标移到【解决方案资源管理器】的项目名称上,右键 点击 属性
  • 选择 生成 勾选XML 文档文件(X)
  • 修改为相对路径,到项目的App_Data 文件夹中

再次运行项目后,该 .xml会自动 生成/更新

在 [生成xml文件] 这一步执行完之后,只要是方法/控制器等,如果没有添加注释信息,IDE就会报 警告 级别的错误

解决办法:左侧错误代码添加到项目配置中

此时警告级别错误 该类型的没有了

导入文档

在 services.AddSwaggerGen 中 添加如下代码

var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; //获取文档
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); // 获取文档路径
x.IncludeXmlComments(xmlPath); // 导入注释内容

拆开来写

var xmlName = Assembly.GetExecutingAssembly().GetName().Name; // 获取当前执行程序名称
var xmlFile = $"{xmlName}.xml"; //获取xml文档名称
var basePath = AppContext.BaseDirectory; // 获取项目路径,到bin/debug里面
var xmlPath = Path.Combine(basePath, xmlFile);
x.IncludeXmlComments(xmlPath); // 导入注释内容

因为xml文档名称是已知的,所以还可以简化写法

var basePath = AppContext.BaseDirectory; // 获取项目路径,到bin/debug里面
var xmlPath = Path.Combine(basePath, "blogV330.xml");
x.IncludeXmlComments(xmlPath); // 导入注释内容

试想:如果我的xml文档名称和程序名称不一样,那上面第一种方法就不可行了,而是直接根据生成名称来写进去,虽然缺少了灵活性,但是不会错

完成代码块:

services.AddSwaggerGen(x =>
{
    x.SwaggerDoc("v1", new OpenApiInfo()
    {
        Title = "Web Api",
        Version = "v1",
        Description = "Web Api说明文档",
        TermsOfService = new System.Uri("http://www.bilibili.com"), // 服务条款
        Contact = new OpenApiContact // 联系信息
        {
            Email = "123456@sina.com",
            Name = "zhangping",
            Url = new System.Uri("http://www.taobao.com")
        },
    });
    var basePath = AppContext.BaseDirectory; // 获取项目路径,到bin/debug里面
    var xmlPath = Path.Combine(basePath, "blogV330.xml");
    x.IncludeXmlComments(xmlPath); // 导入注释内容
});

效果展示

控制器添加注释

上图中 WeatherForecast 并没有注释内容

  • 只需要添加一个 true 即可,上面不写,默认是 false

  • 当然,控制器上面也要有注释,不然都是白搭

  • 效果

原理解析:查看 IncludeXmlComments 源码

  • 可见这个方法还有一个参数配置,见词知意,包含控制器xml注释,默认是false
  • 那只需修改为true即可!

启动项目直接进入到 swagger 文档页面

两步即可

  • Configure 中添加 RoutePrefix 信息

配置为空表示直接在根域名(localhost:53952)访问该文件(swagger.json)

  • launchSettings.json中在启动方式中将launchUrl属性改成空字符串 或者 直接删掉 launchUrl 选项

运行即可直接进入到swagger文档界面,此时url如下

Models添加 限制/注解 信息,让字段信息更丰富

  1. 先展示出来,然后再考虑如何丰富注释

  2. 对api方法的隐藏(不想展示出来时的做法)

新建Model并展示注释说明

  • 解决方案中新建 .net standard 类库项目

  • 创建实体类Article
using System;
using System.Collections.Generic;
using System.Text;

namespace blog.Models
{
    /// <summary>
    /// 文章
    /// </summary>
    public class Article
    {
        /// <summary>
        /// id
        /// </summary>
        public Guid Id { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 作者
        /// </summary>
        public string Author { get; set; }

        /// <summary>
        /// 类别
        /// </summary>
        public string Category { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 删除状态
        /// </summary>
        public bool IsDelete { get; set; } = false;
    }
}
  • 在blogV330项目中引用类库项目

依赖项--右键-->添加引用

选中类库 并确认

效果

  • 在blog.Models项目中配置生成 .xml 文件

  • 在Startup.cs中导入注释内容

  • 在blogV330项目中添加控制器 ArticleController
using blog.Models;
using Microsoft.AspNetCore.Mvc;

namespace blogV330.Controllers
{
    /// <summary>
    /// 文章Api
    /// </summary>
    [ApiController]
    [Route("[controller]/[action]")]
    public class ArticleController : ControllerBase
    {
        /// <summary>
        /// post请求
        /// </summary>
        /// <param name="article"></param>
        [HttpPost]
        public void Post(Article article)
        {

        }
    }
}

最少添加一个方法,否则swagger文档不会显示models和控制器

效果

隐藏控制器或方法,使其不在swagger文档中展现

方案:

  1. 在控制器或者方法上添加特性: [ApiExplorerSettings(IgnoreApi =true)]  
  2. 控制器或方法的修饰符改成 private
[HttpGet]
[Route("get1")]
public void Get1()
{

}

[HttpGet]
[Route("get2")]
private void Get2()
{

}

[HttpGet]
[Route("get3")]
[ApiExplorerSettings(IgnoreApi =true)]
public void Get3()
{

}
  • 效果

如上:get2和get3都没有展现出来

给api方法添加 响应类型 描述

一个方法在被请求访问时,会有不同的响应类型,例如200表示成功,400表示失败,500表示服务器报错等等

  • 修改前样式

  • 修改后样式

具体做法:在方法上添加特性 ProducesResponseType, 在注释中添加 response 信息

若注释信息不添加,请求备注则会显示默认值,例如200 ---> Success , 400 ---> Bad Request  等

  • 代码实现
/// <summary>
/// get1请求
/// </summary>
/// <response code="200">请求成功标志备注</response>
/// <response code="400">请求失败标志备注</response>
[HttpGet]
[Route("get1")]
[ProducesResponseType(typeof(Article), 200)]
[ProducesResponseType(400)]
public void Get1()
{

}

注:typeof(models) 参数可不写