当我有自定义基本 URL 时,如何使用 swagger 设置 Swashbuckle v5?

Lis*_*rie 10 swagger .net-core-3.1 swashbuckle.aspnetcore

我正在将 .net API 升级到 .net Core 3.1 并使用 Swashbuckle.AspNetcore 5.4.1。API 在 ServiceFabric 应用程序中运行。我找到了这个https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1173并尝试遵循它并生成 swagger 但如果我尝试使用 Swagger UI 发送请求请求 URL 使用错误的 IP 所以请求失败。在旧的 Swashbuckle 4.0.1 设置中,我们没有指定主机,只指定相对 basePath。我怎样才能达到同样的目标?

启动文件

var swaggerBasePath = "/MySfApp/SfApp.ClientApi/";

app.UseSwagger(c =>
{
    c.SerializeAsV2 = serializeAsSwaggerV2;
    
    c.RouteTemplate = "swagger/{documentName}/swagger.json";
    c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
    {
        swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}{swaggerBasePath}" } };
    });
});

app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("api/swagger.json", "My API V1");
});
Run Code Online (Sandbox Code Playgroud)

结果是 Swagger UI 在 URL 上正确加载:

http://145.12.23.1:54000/MySfApp/SfApp.ClientApi/swagger/index.html
Run Code Online (Sandbox Code Playgroud)

它在名称下说 BaseUrl 是:

[ Base URL: 10.0.0.4:10680/MySfApp/SfApp.ClientApi/ ]
Run Code Online (Sandbox Code Playgroud)

10.0.0.4:10680 是 ServiceFabric 集群内的节点。从外部访问的正确 IP 是 145.12.23.1:54000。在 Swashbuckle 的旧版本 (4.0.1) 中,它首先显示没有 IP 的 baseUrl:“/MySfApp/SfApp.ClientApi”

Swagger.json 位于:

http://40.68.213.118:19081/MySfApp/SfApp.ClientApi/swagger/api/swagger.json
Run Code Online (Sandbox Code Playgroud)

它说:

"swagger": "2.0",
... 
"host": "10.0.0.4:10680",  
"basePath": "/MySfApp/SfApp.ClientApi/",
"schemes": [
"http"
],
"paths": {
"/activity/{activityId}": {
"get"
...etc
Run Code Online (Sandbox Code Playgroud)

如果我尝试从 Swagger UI 发送 GET 请求,该请求将发送到错误的 IP:

curl -X GET "http://10.0.0.4:10680/MySfApp/MySfApp/activity/3443"
Run Code Online (Sandbox Code Playgroud)

编辑 1:经过一些挖掘后,我现在在 startup.cs 中将设置更改为此

var swaggerBasePath = "/MySfApp/SfApp.ClientApi/";
app.UsePathBase($"/{swaggerBasePath}");
app.UseMvc();
app.UseSwagger(c =>
{
    c.SerializeAsV2 = serializeAsSwaggerV2;

    c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
    {
        if (!httpReq.Headers.ContainsKey("X-Original-Host")) 
            return;

        var serverUrl = $"{httpReq.Headers["X-Original-Proto"]}://" +
                        $"{httpReq.Headers["X-Original-Host"]}/" +
                        $"{httpReq.Headers["X-Original-Prefix"]}";

        swaggerDoc.Servers = new List<OpenApiServer>()
        {
            new OpenApiServer { Url = serverUrl }
        };
    });
});
app.UseSwaggerUI(options => {
    options.SwaggerEndpoint("api/swagger.json", "My API V1");
});
Run Code Online (Sandbox Code Playgroud)

这现在会使用 baseUrl 正确加载 Swagger UI

http://145.12.23.1:54000/MySfApp/SfApp.ClientApi/swagger/index.html
Run Code Online (Sandbox Code Playgroud)

并且 swagger.json 使用正确的 baseUrl 正确提供。

http://145.12.23.1:54000/MySfApp/SfApp.ClientApi/swagger/api/swagger.json
Run Code Online (Sandbox Code Playgroud)

这样就解决了错误的主机名。感谢这个线程的想法

但是,当我尝试从 Swagger UI 页面调用端点时,curl URL 不包含 baseUrl。如此接近......但目前无法使用 Swagger UI。

curl -X GET "http://10.0.0.4:10680/activity/3443"
Run Code Online (Sandbox Code Playgroud)

swagger.json 没有定义 'host' 和 'basePath'。

Thi*_*uND 0

试试这个: serverUrl = $"{httpReq.Headers["X-Forwarded-Proto"]}://" + $"{httpReq.Headers["X-Forwarded-Host"]}" + _basePath; 其中 _basePath 可以使用 StatelessServiceContext 的 ServiceName 属性进行设置。请注意,X-Forwarded-Proto 的原始值可能会被 SF 覆盖。