You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core项目可访问swagger.json但Swagger UI页面无法显示

问题现象

访问http://localhost:5000/swagger/index.html时Swagger UI无法正常加载显示,但访问http://localhost:5000/swagger/v1/swagger.json可正常获取swagger.json内容,且该文件可正常导入Postman使用。相关配置代码如下:

现有配置代码

Program.cs 代码内容

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

Startup.cs - Configure方法配置

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(o => o.GroupName))
    {
        c.SwaggerEndpoint(
            $"/swagger/{description.GroupName}/swagger.json",
            description.GroupName.ToUpperInvariant());
    }
});

Startup.cs - ConfigureServices方法配置

//Swagger Services.
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
if (this.Configuration["EnableSwagger"] == "true")
{
    //services.AddSwaggerGen(opt =>
    //opt.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });

    //// Set the comments path for the Swagger JSON and UI.
    //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    //var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    //opt.IncludeXmlComments(xmlPath);
    services.AddSwaggerGen(opt =>
    {
        opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Name = "Authorization",
            Type = SecuritySchemeType.ApiKey,
            Scheme = "bearer",
            BearerFormat = "JWT",
            In = ParameterLocation.Header,
            Description = "JWT Authorization header using the Bearer scheme."
        });
        opt.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
              new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer"
                    }
                },
                Array.Empty<string>()
            }
        });
    });
}

自定义ConfigureSwaggerOptions类实现

public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
    readonly IApiVersionDescriptionProvider _apiVerProvider;

    public ConfigureSwaggerOptions(IApiVersionDescriptionProvider apiVerProvider) => _apiVerProvider = apiVerProvider;

    public void Configure(SwaggerGenOptions options)
    {
        foreach (var description in _apiVerProvider.ApiVersionDescriptions)
        {
            options.SwaggerDoc(description.GroupName, GetSwaggerDocInfo(description));
        }
    }

    static OpenApiInfo GetSwaggerDocInfo(ApiVersionDescription description)
    {
        var info = new OpenApiInfo
        {
            Title = $"WebAPI {description.ApiVersion}",
            Version = description.GroupName,
            Description = "Web API Template",
            Contact = new OpenApiContact()
            {
                Name = "Web API service"
            },
            License = new OpenApiLicense()
            {
                Name = "MIT"
            }
        };

        if (description.IsDeprecated)
        {
            info.Description += $" {description.ApiVersion} API version is deprecated.";
        }
        return info;
    }
}
排查方向与解决方案

按照优先级从高到低排查:

  • 静态文件中间件缺失或顺序错误
    Swagger UI的前端页面、JS、CSS资源依赖静态文件中间件加载,缺省该配置时会出现swagger.json可访问但UI资源全部404的问题。
    修复方式:调整Configure方法中间件顺序,确保app.UseStaticFiles()在Swagger相关中间件之前调用,参考正确顺序:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider)
    {
        // 其他业务中间件、异常处理中间件
        app.UseStaticFiles(); // 必须放在Swagger中间件前
        app.UseRouting();
    
        // Swagger相关中间件建议和服务注册保持相同的条件判断
        if (Configuration["EnableSwagger"] == "true")
        {
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.RoutePrefix = "swagger"; // 显式指定路由前缀,避免默认值被覆盖
                foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(o => o.GroupName))
                {
                    c.SwaggerEndpoint(
                        $"/swagger/{description.GroupName}/swagger.json",
                        description.GroupName.ToUpperInvariant());
                }
            });
        }
    
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    
  • Swagger路径被认证/自定义中间件拦截
    打开浏览器F12开发者工具,切换到「网络」面板刷新Swagger UI页面,查看加载失败的资源状态码:

    • 若状态码为401/403:说明全局认证中间件拦截了Swagger的静态资源请求,需要在认证策略中放行/swagger/**所有路径
    • 若状态码为302跳转到登录页/错误页:检查全局授权过滤器、URL重写中间件是否添加了Swagger路径排除规则
  • Swagger服务注册逻辑不一致
    当前代码中ConfigureSwaggerOptions注册在EnableSwagger判断条件外,但AddSwaggerGen的安全配置在条件内,Swagger中间件调用没有加条件判断,容易出现配置半加载的异常状态。
    修复方式:把所有Swagger相关的服务注册(包括ConfigureSwaggerOptions、AddSwaggerGen)和中间件调用(UseSwagger、UseSwaggerUI)统一放在相同的EnableSwagger判断块内,避免配置不匹配。

  • 环境兼容或缓存问题

    • 如果部署在Linux等大小写敏感的系统上,检查Swagger相关路径的大小写和配置完全一致
    • 清空浏览器缓存或使用无痕模式访问,排除旧的错误静态资源缓存影响

内容的提问来源于stack exchange,提问作者syma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:09:36