当前位置: 首页 >资讯 >

每日头条!为控制器生成OpenAPI注释

来源:博客园 2023-07-04 14:25:32

非常喜欢. NET 的 ///注释,写代码的时候就顺道完成写文档的过程,简直不要太爽了。 ASP. NET CORE 也是一样的,通过 Swagger工具,可以自动生成 API 的接口文档(OpenAPI规范),提供给前端使用,也可以用过 APIPOST/APIFOX 之类的工具提供给前端同学直接调用。

生成 OpenAPI 注释

只需要安装 swashbuckle.aspnetcore包,在项目上设置生成 XML 格式的注释,并且如下配置即可自动生成 OpenAPI 的文档,对我这个例子,可以通过 swagger/v{version}/swagger.json访问。

services.AddSwaggerGen(options =>            {                // options.CustomSchemaIds(type => type.AssemblyQualifiedName);                var fileName = Assembly.GetExecutingAssembly().GetName().Name + ".xml";                var filePath = Path.Combine(AppContext.BaseDirectory, fileName);                // integrate xml comments                options.IncludeXmlComments(filePath);            });                app.UseSwagger();                app.UseSwaggerUI(                    options =>                    {                        foreach (var description in app.DescribeApiVersions())                        {                            var url = $"/swagger/{description.GroupName}/swagger.json";                            var name = description.GroupName.ToUpperInvariant();                            options.SwaggerEndpoint(url, name);                        }                    });

注释如下:


(资料图)

///     /// 这个接口    ///     public class CoverageDataController : ODataController{        ///         /// 获取盖度数据        ///         ///         ///         ///         [HttpGet]        [ProducesResponseType(typeof(CoverageDataDto), Status200OK)]        public async Task Get(string key, ODataQueryOptions options)        {        }    }
生成 Tags 注释

在使用 APIFOX 导入 swagger.json导入时,我发现,对每一个 path 的注释能够正常显示,但是对的控制器的注释不能正常被识别。

查看生成的 swagger.json,这个 CoverageData 被解释成了 OpenAPI 的 Tags,那对应控制器的相关注释,是需要使用另外的标注实现的,而不能直接使用///的注释实现。

paths": {        "/api/v{version}/CoverageData({key})": {            "get": {                "tags": [                    "CoverageData"                ],                "summary": "获取盖度数据",

安装的新的包 swashbuckle.aspnetcore.annotations,然后增加启用语句,如下:

services.AddSwaggerGen(options =>            {                // options.CustomSchemaIds(type => type.AssemblyQualifiedName);                var fileName = Assembly.GetExecutingAssembly().GetName().Name + ".xml";                var filePath = Path.Combine(AppContext.BaseDirectory, fileName);                // integrate xml comments                options.IncludeXmlComments(filePath);                options.EnableAnnotations();            });

在控制器的声明上面,添加 [SwaggerTag("接受盖度数据")]注解:

///     /// 这个接口    ///     [SwaggerTag("接受盖度数据")]    public class CoverageDataController : ODataController{    }

最后生成的 swagger.json文件在末尾多了几行:

"tags": [        {            "name": "CoverageData",            "description": "接受盖度数据"        }    ]

Swagger 里面就可以看到注释了:

但是导入到 APIFOX 中,显示的组别名称依然是 CoverageData ,没有达到我想要的效果,我想将其替换成可以显示友好的名称。实质上是为 CoverageData 取一个别名。

注:这种方法不能与 swagger 配置的 TagActionsBy 方法的一起使用。

Tags 注解

在 ASP. NET CORE 中,可以在控制器上使用 [Tags("盖度接口")],对控制器的组别进行标注。这样生成的 tag 名称直接就换成了的中文名称。

"paths": {        "/api/v{version}/CoverageData({key})": {            "get": {                "tags": [                    "盖度接口"                ],                "summary": "获取盖度数据",....    "tags": [        {            "name": "CoverageData",            "description": "接受盖度数据"        }    ]

但是 swagger 变得非常奇怪:

出现了两个不同的 tag,其中 CoverageData 名称的下面没有从属的 api。

如果没有对 Tag 写 description 的要求,那么使用这个方案是最简单的:设置[Tags],不要设置[SwaggerTag]。

DisplayName 注解

这么看应该是通过 swagger 生成的 tag 与通过 [Tags]注解生成的 tag 对象不能匹配,导致 swagger 生成的没用被引用。

查了很久资料,说这个是一个现在的 Bug,有人通过重写 DisplayName,在帖子中给了临时的解决方案:

先增加一个新的类型。
/// /// Uses the [DisplayName] attribute as the Controller name in OpenAPI spec and Swagger/ReDoc UI if available else the default Controller name./// public class ControllerDocumentationConvention : IControllerModelConvention{    void IControllerModelConvention.Apply(ControllerModel controller)    {        if (controller == null)        {            return;        }                foreach (var attribute in controller.Attributes)        {            if (attribute is DisplayNameAttribute displayNameAttribute && !string.IsNullOrWhiteSpace(displayNameAttribute.DisplayName))            {                controller.ControllerName = displayNameAttribute.DisplayName;            }        }    }}
给 Controller 配置这个命名转换。
services.AddControllers(o =>{   o.Conventions.Add(new ControllerDocumentationConvention());});
在需要调整名称的控制器上添加 [DisplayName("targetNames")]即可。可以看到名称与注释都得到的保留,最终效果如下:

导入 APIFOX 也可以正常识别了。

参考资料swagger ui - How to provide OpenAPI "tag" group descriptions for a .NET Core 7 minimal API? - Stack OverflowTagActionsBy custom tag or controller name · Issue #467 · domaindrivendev/Swashbuckle.AspNetCore (github.com)Support for associating XML Comments with custom tags defined using TagsAttribute by yingxinj · Pull Request #2565 · domaindrivendev/Swashbuckle.AspNetCore (github.com)
相关阅读

关键词:

大家还在看
热词