Net Core 3.1 Swagger & Versioning 整合-踩出所有陨石坑的填坑集合

  • Post author:
  • Post category:其他


本文主要讲述一个傻瓜-本人,经过艰辛万苦,填了各种陨石坑,最后一不小心就调试成功的喜悦,和大家分享下。

开门见山的讲故事,可以看出本文讲的就是API接口文档和版本控制的整合操作配置过程,感觉网上有说到的坑我都踩了一下,所以整理出来给以后年老不记得事的自己。

错误一:No operations defined in spec!   解决=》根本原因就是,路由并没有发现可用的路径。

错误二:Unable to render this definition。解决=》api中的Controller/Action 加入[HttpPost]或者 [HTTPGet]

错误三:访问“服务URL:端口/swagger/index.html”访问不到版本控制,版本控制页面地址应为“服务URL:端口/index.html”

下面科普天文,开始讲陨石坑的故事:

我没有安装过,不过很多网友反映Swashbuckle.AspNetCore 2.0之前的版本会有很多的不兼容情况,很多问题会出现。据网友目击报道说是这个版本的UI有问题会发生类似“No operations defined in spec! ”的问题,所以最好与时俱进使用最新版本,方便省心。

所以先呈现以下我所有已安装的包版本:

开始操作流程:

一、使用Nuget安装微软官方提供的一个可用的Api版本控制库Microsoft.AspNetCore.Mvc.Versioning。

1、使用Nuget安装Api版本控制库Versioning

2、在StartUp.cs中的ConfigureServices添加:

services.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;//return versions in a response header
                o.DefaultApiVersion = new ApiVersion(1, 0);//default version select 
                o.AssumeDefaultVersionWhenUnspecified = true;//if not specifying an api version,show the default version
            });

3、添加不同版本的主目录文件夹v1、v2…vn,在文件夹下面添加测试用的controller

4、在controller的文件上面加上Attribute,别的controller除了ApiVersion的版本1需要修改,别的都不用修改。

[ApiVersion("1")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]

5、接下来就可以测试了,分别输入地址

http://localhost:1310/api/v1/vt02/1



http://localhost:1310/api/v2/vt02/1

,看下显示。

成功显示和预期无差别。

二、安装Swagger

1、使用Nuget来查找安装Swashbuckle.AspNetCore。

2、在vs2019的调试 – 属性 – 生成(左边栏)

1*在取消显示警告中添加编号:1591。

2*输出中点XML文档文件 – 选择路径:C:\Users\win7develop\source\repos\NetCoreTest02\NetCoreTest02.xml

3、写2个过滤器

public class SetVersionInPathDocumentFilter: IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            var updatedPaths = new OpenApiPaths();
            foreach (var entry in swaggerDoc.Paths)
            {
                updatedPaths.Add(
                    entry.Key.Replace("v{version}", swaggerDoc.Info.Version),
                    entry.Value);
            }
            swaggerDoc.Paths = updatedPaths;
        }
    }

    public class RemoveVersionParameterOperationFilter: IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            // Remove version parameter from all Operations
            var versionParameter = operation.Parameters.Single(p => p.Name == "version");
            operation.Parameters.Remove(versionParameter);
        }
    }

4、在ConfigureServices中注册以下服务。

services.AddSwaggerGen(s =>
            {
                //Version will show in url
                s.SwaggerDoc("v1", new OpenApiInfo
                {
                    Contact = new OpenApiContact
                    {
                        Name = "Kilven",
                        Email = "Kilven@hotmail.com",
                        Url = new Uri("https://me.csdn.net/wobaiwodedukuku")
                    },
                    Description = "A front-background project build by ASP.NET Core 3.1 and Vue",
                    Title = "NetCoreTest02 API v1",
                    Version = "v1.0"
                });
                s.SwaggerDoc("v2", new OpenApiInfo
                {
                    Contact = new OpenApiContact
                    {
                        Name = "Kilven",
                        Email = "Kilven@hotmail.com",
                        Url = new Uri("https://me.csdn.net/wobaiwodedukuku")
                    },
                    Description = "A front-background project build by ASP.NET Core 3.1 and Vue",
                    Title = "NetCoreTest02 API v2",
                    Version = "v2.0"
                });
                //这步很重要,将Swagger中显示出的"v'n'"进行替换,使显示同步。
                s.DocInclusionPredicate((docName, apiDescription) =>
                {
                    var versions = apiDescription.CustomAttributes()
                                    .OfType<ApiVersionAttribute>()
                                    .SelectMany(attr => attr.Versions);

                    return versions.Any(v => $"v{v.ToString()}" == docName);
                });
                //添加2个过滤器
                s.OperationFilter<RemoveVersionParameterOperationFilter>();
                s.DocumentFilter<SetVersionInPathDocumentFilter>();
                //项目xml文档
                s.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml"), true);
                //这里包含了一个Demo.Model.xml,是来显示实体类。
                //s.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"Demo.Model.xml"), true);
            });

5、在Configure中添加代码

app.UseSwagger();
            app.UseSwaggerUI(s =>
            {
                s.SwaggerEndpoint("/swagger/v1/swagger.json", "NetCoreTest02 API v1");
                s.SwaggerEndpoint("/swagger/v2/swagger.json", "NetCoreTest02 API v2");

                s.RoutePrefix = string.Empty;
                s.DocumentTitle = "NetCoreTest02 API";
            });

6、运行测试成功。

再确认下代码,加一个注释看看好不好用!

最后留言:此路艰难,且行且珍惜,愿天下无坑!



版权声明:本文为wobaiwodedukuku原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。