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

.NET 8与Azure应用服务计划下微服务API路由问题求助

问题:Azure路径路由下Swagger验证端点返回404

我正在开发基于.NET 8的三微服务项目,三个微服务部署在同一Azure应用服务计划下的独立Azure App Service中。生产环境配置了路径路由规则:/m1/*请求路由至m1服务,m2、m3同理。

本地通过Swagger验证端点正常,但部署后访问https://testapi.com/m1/docs/index.html能打开Swagger页面,验证端点时却返回HTTP 404错误。

提供的Swagger配置代码及引用包信息如下:

Swagger配置代码

public static void UseSwaggerExtension(this IApplicationBuilder app, IWebHostEnvironment env, string appName)
{
    bool enableSwagger = FeatureManagerService.IsFeatureEnabled(nameof(FeatureFlags.EnableSwagger));

    if (!enableSwagger) { return; };

    app.UseSwagger(c =>
    {
        c.RouteTemplate = $"docs/{{documentName}}/openapi.json";
    });

    ConfigureSwaggerForPROD(app, env, appName);

    app.UseSwaggerUI(config =>
    {
        config.SwaggerEndpoint("v1/openapi.json", "Version 1");
        config.RoutePrefix = $"docs";
        config.DocExpansion(DocExpansion.List);
        config.DisplayRequestDuration();
        config.DefaultModelsExpandDepth(-1);
    });
}

private static void ConfigureSwaggerForPROD(IApplicationBuilder app, IWebHostEnvironment env, string appName)
{
    if (env.IsProduction())
    {
        app.UseSwagger(c =>
        {
            string basePrefix = appName.Equals(Contants.M3, StringComparison.CurrentCultureIgnoreCase) ? "m3" : appName.ToLower();

            c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
            swaggerDoc.Servers = [
                                        new() { Url = $"/{basePrefix}"}
                                 ]);
        });
    }
}

引用包

<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />

排查与解决方案

核心问题方向

出现该问题的核心原因通常是Swagger生成的API请求路径与Azure路由规则、服务内部路由不匹配,或Swagger配置存在冲突。以下是具体排查步骤和修复方案:

1. 检查Azure路径路由的前缀剥离设置

登录Azure门户,进入应用服务的「配置」→「路径映射」,查看对应微服务的路由规则:

  • 若设置了「路径前缀」为/m1:Azure会自动剥离该前缀,服务内部收到的请求路径不含/m1,此时Swagger的Server配置理论上是正确的;
  • 若仅设置「匹配路径」为/m1/*未配置路径前缀:服务会收到完整的/m1/xxx请求路径,而服务内部路由是/xxx,导致匹配失败返回404。

2. 修复Swagger重复配置问题

代码中两次调用app.UseSwagger会添加两个Swagger中间件,可能导致配置冲突。需合并Swagger配置,避免重复调用:

public static void UseSwaggerExtension(this IApplicationBuilder app, IWebHostEnvironment env, string appName)
{
    bool enableSwagger = FeatureManagerService.IsFeatureEnabled(nameof(FeatureFlags.EnableSwagger));
    if (!enableSwagger) { return; };

    app.UseSwagger(c =>
    {
        c.RouteTemplate = $"docs/{{documentName}}/openapi.json";

        // 合并生产环境配置到同一个UseSwagger调用中
        if (env.IsProduction())
        {
            string basePrefix = appName.Equals(Contants.M3, StringComparison.CurrentCultureIgnoreCase) ? "m3" : appName.ToLower();
            c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
            {
                swaggerDoc.Servers = new List<OpenApiServer>
                {
                    new OpenApiServer { Url = $"/{basePrefix}" }
                };
            });
        }
    });

    app.UseSwaggerUI(config =>
    {
        config.SwaggerEndpoint("v1/openapi.json", "Version 1");
        config.RoutePrefix = $"docs";
        config.DocExpansion(DocExpansion.List);
        config.DisplayRequestDuration();
        config.DefaultModelsExpandDepth(-1);
    });
}

3. 配置UsePathBase适配Azure路径前缀

如果Azure路由未剥离前缀,需在服务中配置UsePathBase,让服务自动识别并剥离请求的基础路径:

// 在Program.cs的路由配置前添加(需传入对应appName)
if (env.IsProduction())
{
    string basePrefix = appName.Equals(Contants.M3, StringComparison.CurrentCultureIgnoreCase) ? "m3" : appName.ToLower();
    app.UsePathBase($"/{basePrefix}");
}

4. 验证openapi.json内容

访问https://testapi.com/m1/docs/v1/openapi.json,检查两个关键字段:

  • servers:确认值为[{"url":"/m1"}],确保Swagger生成的API请求带有正确前缀;
  • paths:确认API路径为服务内部的原始路径(如/api/values),而非带有/m1的路径。

内容的提问来源于stack exchange,提问作者santosh kumar patro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:57:33