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

本文主要講述一個傻瓜-本人,經過艱辛萬苦,填了各種隕石坑,最後一不小心就調試成功的喜悅,和大家分享下。

開門見山的講故事,可以看出本文講的就是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/1http://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 = "[email protected]",
                        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 = "[email protected]",
                        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、運行測試成功。

再確認下代碼,加一個註釋看看好不好用!

最後留言:此路艱難,且行且珍惜,願天下無坑!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章