.net core 3.1 WebApi項目---Swagger支持二級目錄


1、swagger的二級目錄問題

.net core 3.1環境下,我們采用的是引入 Swashbuckle.AspNetCore包產生swagger的json文件,以及swagger ui。配置相對簡單,估計百度上有很多了,這里也可以參考如下:
這里集成了jwt的授權頭設定 。

public void ConfigureServices(IServiceCollection services)
{
           services.AddSwaggerGen(c =>
            {

                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "后台API接口文檔",
                    Description = "API",
                });
                //Set the comments path for the swagger json and ui.
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                var xmlPath = Path.Combine(basePath, "XXX.Apis.xml");
                var dtolXmlPath = Path.Combine(basePath, "XXX.Service.xml");

                c.IncludeXmlComments(xmlPath);
                c.IncludeXmlComments(dtolXmlPath);                
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Description = "在下框中輸入請求頭中需要添加Jwt授權Token:Bearer Token",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[] { }
                    }
                });
                //c.EnableAnnotations();
            });
            // .net core 支持newstonsoftjson
            services.AddSwaggerGenNewtonsoftSupport();
}

  在配置app內增加

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory factory)
{
app.UseSwagger();

            // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "App API V1");
            });
}

  

如果采用忽略二級目錄(不轉發二級目錄)的nginx配置方式,直接訪問api是沒有問題的,因為.net core app根本就沒接收到二級目錄。
直接訪問swagger ui也是沒問題的,然而在載入 swagger.json時由於是js載入的路徑,會自動帶上二級目錄,這時候提示 【找不到\二級目錄\swagger\v1\swagger.json】的錯誤提示,到此一步,我竟然輕易就放棄了。

以下是我的想法,未驗證:
這時候應該可以直接修改swaggerui配置如下:

app.UseSwaggerUI(c =>
 {      
          c.SwaggerEndpoint($"/{VDir}/swagger/v1/swagger.json", "Vbms App API V1");
          c.RoutePrefix = $"{VDir}/swagger";     
  });

  

因為沒有測試,不能說一定成功,有時間我測試下這個想法。

2、增加虛擬目錄配置,並支持
首先nginx的配置仍然按照正常轉發,二級目錄直接轉發到.net core app內,這時候對swagger進行如下配置,該配置是翻閱了asp.net core和swagger部分代碼而知的,獨家分享:

// 1.生成json文件時,生成到虛擬目錄下,VDir 來自配置
app.UseSwagger(c =>
  {
       if (!string.IsNullOrEmpty(VDir))
       {
          // 設定模板:by webmote csdn
           c.RouteTemplate = $"/{VDir}/swagger/{{documentName}}/swagger.json";
           c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
           {
               //api測試時增加虛擬目錄 或完整路徑也可以,完整路徑已被webmote注釋
               swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer {
               Url = $"/{VDir}"
              //  Url = $"{httpReq.Scheme}://{httpReq.Host.Value}/{virtualPath}"
           } };
           });
       }
   });

   // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
   app.UseSwaggerUI(c =>
   {
       if (!string.IsNullOrEmpty(VDir))
       {
           c.SwaggerEndpoint($"/{VDir}/swagger/v1/swagger.json", "App API V1");
           c.RoutePrefix = $"{VDir}/swagger";
       }
       else
       {
           c.SwaggerEndpoint("/swagger/v1/swagger.json", "App API V1");
       }
   });

  

3、對Api增加虛擬目錄支持
如果二級目錄是固定的,你在控制期路由時,直接寫死也是一個辦法,只是不太靈活,哈哈。
例如: [Route("二級目錄/api/[controller]/[action]")]
微軟的某一篇文章說 使用 ~開頭的路由路徑可以支持虛擬目錄,我試了,不行!

這里采用的時.net core 3引入的動態自定義路由方案,可以靈活配置。 增加自定義的路由轉換類

public class MyTransformer : DynamicRouteValueTransformer
    {
        private string _route = string.Empty;
        public MyTransformer(string route)
        {
            _route = route;
        }
        public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
        {
            if (!values.ContainsKey("dir")) return new ValueTask<RouteValueDictionary>(values);

            var dir = (string)values["dir"];
            return new ValueTask<RouteValueDictionary>(values);
        }
    }

  這里引入了{dir}路由配置,把該類注入到服務中

if (!string.IsNullOrEmpty(VDir))
 {
      services.AddSingleton<MyTransformer>(new MyTransformer(VDir));
  }

  在終結點配置時,增加對二級目錄的路由解釋映射。

app.UseEndpoints(endpoints =>
  {
       endpoints.MapControllers();
       if (!string.IsNullOrEmpty(VDir))
       {
           //這里是webmote定義的路由映射,可以方便的忽略二級目錄
           endpoints.MapDynamicControllerRoute<MyTransformer>("{dir}/api/{controller}/{action}/{id?}");
       }
   });

  

控制器WebApi的路由保持不變,不需要增加二級目錄的!
[Route("api/[controller]/[action]")]

4、結語
當遇到特別難處理的問題時,最好的辦法時先搜索看看有無前輩解決過類似問題,如果沒有的話,那就別遲疑了,快快翻看源代碼,仔細查閱下有什么辦法可以注入處理程序,攔截下原有處理方式。
————————————————
版權聲明:本文為CSDN博主「webmote」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/codeex/article/details/104599929


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM