ASP.NET Core 接口文档解决方案(swagger)

发布时间 2023-05-19 19:55:32作者: AI大胜

api文档解决方案很多,先介绍我用过的两种方案:

比较项 Swagger Showdoc
官网 帮助说明--ShowDoc
知名度 较大、net6 官方推荐 国产
在线测试 支持 不支持
文档定义方式 注释为主 注释为主
生成过程 自动根据接口参数和返回类型生成相关说明。 接口文档的一切都需在注释中自定义。手写内容较多,但能使文档更清楚直观。
依赖和文档更新 依附于接口程序,共生。 可通过一些简单操作,实现一键快速更新。像是个单独网站。
下载分享 支持下载 支持下载。可分享指定接口,或整个项目接口,且支持网址密码分享。有成员概念。

个人目前偏爱 showdoc,虽然它不能在线测试以及需要编写较多的注释,但真的好用。参考:帮助说明--ShowDoc

Swagger 介绍

Swagger (OpenAPI) 是一个与语言无关的规范,用于描述 REST API。

简而言之:

  • OpenAPI 是一种规范。
  • Swagger 是一种使用 OpenAPI 规范的工具。 例如,OpenAPIGenerator 和 SwaggerUI。

Swagger UI 提供了基于 Web 的 UI,它使用生成的 OpenAPI 规范(json)提供有关服务的信息。Web UI 如下所示:

Swagger UI

在net 6中的使用Swagger

入门教程

在ASP.NET Core中的使用步骤,参考(重要,请必读跟着做):
Get started with Swashbuckle and ASP.NET Core | Microsoft Docs

简单看看跟着操作下就好,适合入门了解,但挺鸡肋。

实际应用保姆级教程

先引用netget包:

  • Swashbuckle.AspNetCore
  • Swashbuckle.AspNetCore.Annotations
  • IGeekFan.AspNetCore.Knife4jUI //这个提供更美观好用的页面,是一热心网友做的开源优质皮肤。

编辑项目文件

打开接口的项目文件,设置要生成接口文档描述:

image-20230519174427712

<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>D:\AMyProject\web-idasheng\WebApi\ApiDocs\WebApi.xml</DocumentationFile>

其中,DocumentationFile 节点的路径可自定义,这个路径很重要。

然后点击重新生成解决方案。这时会看到生成的该xml文件,然后选中右击,点击【属性】,在“复制到输出目录”项,选择【始终复制】。以便发布时能带上该文件。


注意:对接口入参或返回数据中,涉及到的模型类,要在他们所在的项目,也要进行上面这样的设置,以便接口文档自动应用相关属性的注释说明。

image-20230519175018630

这些模型类,要加上属性的注释,后面它就是接口文档的字段说明。像这样:

image-20230519182724582

设置分组

一个软件系统的接口文档有很多,需要分组(或分版本),以便管理和查看,这里可以先建一个分组信息类:

public class ApiGroupInfo
    {
        public const string 开发测试= "开发测试";
        public const string 公开服务= "公开服务";
        public const string 官网相关= "官网相关";
        public const string 其它= "其它";
    }

然后在每个控制器中应用分组标识,多个控制器可以共用一个分组,就像这样:

image-20230519175639939

[Produces("application/json")]
[ApiExplorerSettings(GroupName = ApiGroupInfo.公开服务)]

具体的方法,主要就是写注释啦,swagger根据注释信息,生成文档描述。大概是下面这么个形式:

/// <summary>
        /// 获取应用信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAppInfo()
        {
            return new JsonResult(_sysConfig.AppInfo);
        }

        /// <summary>
        /// 获取中国传统色
        /// </summary>
        /// <param name="key">访问key</param>
        /// <returns></returns>
        [HttpGet]
        [ProducesDefaultResponseType(typeof(IEnumerable<Public_CnColors>))]
        public async Task<string> GetCnColors(string key)
        {
            var data = await new BasicCRUD<Public_CnColors>().GetList();

            return EachData.Success(data);
        }

        /// <summary>
        /// 获取中国传统色2
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<EachData<IEnumerable<Public_CnColors>>> GetCnColorsV2(string key)
        {
            var data = await new BasicCRUD<Public_CnColors>().GetList();

            return EachData<IEnumerable<Public_CnColors>>.Success(data);
        }

服务注册

下面代码,根据上面提到的分组类,遍历每个组信息,以便在接口文档形成分组下拉菜单。

然后对前文设置的xml文档进行了使用。

最后还配置了jwt bearer 授权,以便接口调试时携带该信息。

#region 服务注册:接口文档Swagger
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
    var desc = "请熟读并背诵接口文档。 ";
    var constantProperties = typeof(ApiGroupInfo)
    .GetFields(BindingFlags.Public | BindingFlags.Static)
    .ToArray();
    foreach (var field in constantProperties)
    {
        options.SwaggerDoc(field.Name, new OpenApiInfo
        {
            Version = field.Name,
            Title = field.Name,
            Description = desc
        });

    }
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlApiPath = Path.Combine(AppContext.BaseDirectory, $"ApiDocs/{Assembly.GetExecutingAssembly().GetName().Name}.xml");
    var xmlEntityPath = Path.Combine(AppContext.BaseDirectory, "ApiDocs/Data.Entity.xml");
    var xmlDtoPath = Path.Combine(AppContext.BaseDirectory, "ApiDocs/Data.Dto.xml");
    options.IncludeXmlComments(xmlApiPath, true);
    options.IncludeXmlComments(xmlEntityPath, true);
    options.IncludeXmlComments(xmlDtoPath, true);
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "Value: Bearer {token}",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer",
        BearerFormat = "JWT"
    });
    options.AddSecurityRequirement(new OpenApiSecurityRequirement()
    {
      {
        new OpenApiSecurityScheme
        {
          Reference = new OpenApiReference
          {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
          },Scheme = "oauth2",Name = "Bearer",In = ParameterLocation.Header,
        },new List<string>()
      }
    });
}); 
#endregion

中间件配置

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();

    app.UseSwagger();
    //app.UseSwaggerUI();//使用swagger默认的皮肤样式
    app.UseKnife4UI(c =>
    {
        c.RoutePrefix = String.Empty ; // serve the UI at root
        var constantProperties = typeof(ApiGroupInfo)
    .GetFields(BindingFlags.Public | BindingFlags.Static)
    .ToArray();
        foreach (var field in constantProperties)
        {
            c.SwaggerEndpoint($"/swagger/{field.Name}/swagger.json", $"{field.Name}");
        }
    });
}

这样,它就基本OK了,注意事项:

  • 对接口action,最好标注[HttpGet] [HttpPost]
  • 如果你的action返回类型是string,但其实是返回的是某个类型,那需要对action应用[ProducesDefaultResponseType(typeof(Product))]这个特性,来自动生成对设置类型的字段描述(来自注释)。

运行查看

至此,基本完成了,F5运行,路径定位到根目录,查看效果如下:

image-20230519180916355

查看分组、在线测试,都还挺方便:

image-20230519181027889

image-20230519181114150

ShowDoc (推荐)

Showdoc简介,https://www.showdoc.com.cn/help/1385767280275683

使用程序注释自动生成API文档 https://www.showdoc.com.cn/page/741656402509783

优点

  • 使用简单,在接口程序无需做任何代码配置。完全可自定义请求参数、返回参数、返回数据示例。
  • 可生成带访问密码的共享连接。
  • 可转化成Word文档。
  • 免费。(5人以下团队免费)。
  • 接口文档不依赖接口站点程序。可以自建showdoc服务站点或在官网自建接口文档项目。

缺点

  • 高度依赖方法注释,每个请求参数或返回参数都需要写清楚。
  • 另外暂时无法通过文档直接请求测试接口。

image-20220919150446780

image-20220919150646561


更新于:2023.5.19