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

.NET Core 2.2 API升级至.NET 6后仅返回404响应排查

.NET 6 API升级后前端请求返回404排查建议

我们正将解决方案升级至.NET 6,整体进展顺利,但API出现异常:API可正常构建运行,但前端请求始终返回404响应,目前无法定位问题根源。已尝试多种常见修复方案均无效,推测可能遗漏了构建器配置或未注意到.NET 6的新特性,现寻求解决建议。以下是API相关结构的代码片段,若需更多信息可告知,请忽略注释代码(正在尝试不同方案)。

Program.cs

var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);

var app = builder.Build();
startup.Configure(app, builder.Environment);

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.Run();

Startup.cs

...
            services.AddRazorPages();
            services.AddControllers();
            services.AddHttpContextAccessor();
            services.AddCors(options =>
                options.AddPolicy(MyAllowSpecificOrigins, builder => { builder.WithOrigins("http://localhost:8000", "http://localhost:3000").AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("File-Name").AllowCredentials(); }));            
            //services.AddMvc()
            //    .AddMvcOptions(options => options.EnableEndpointRouting = false)                
            //    .AddJsonOptions(options =>
            //    {
            //        // returning the string enum instead of the int value. 
            //        //options.serializersettings.converters.add(new newtonsoft.json.converters.stringenumconverter());
            //        //options.serializersettings.referenceloophandling = newtonsoft.json.referenceloophandling.ignore;
            //    });
            services.AddAutoMapper(typeof(Startup), typeof(AchFileParseMappings),
                typeof(ModelToResourceProfile), typeof(ResourceToModelProfile));
            //ConfigureSwagger(services);             
            services.AddJsReport(new LocalReporting().KillRunningJsReportProcesses()
                .UseBinary(JsReportBinary.GetBinary())
                .AsUtility()
                .Create());            
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostEnvironment env)
        {                        
            app.UseHttpsRedirection();
            app.UseCurrentUser();
            app.UseMiddleware<ErrorHandlingMiddleware>();
            app.UseMiddleware<ApiLoggingMiddleware>();
            app.UseStaticFiles();
            app.UseAuthorization();
            app.UseAuthentication();
            app.UseRouting();            
            //app.UseMvc();

            app.Use(async (ctx, next) =>
            {
                ctx.Response.Headers.Add("Content-Security-Policy",
                                         "default-src 'self';");
                await next();
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapControllers();
                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
            });

            if (env.IsDevelopment())
            {
                app.UseCors(x => x.WithOrigins("http://localhost:8000", "http://localhost:3000").AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("File-Name").AllowCredentials());
                app.UseDeveloperExceptionPage();
            } 
            else
            {
                app.UseCors(MyAllowSpecificOrigins);
                app.UseHsts();
            }          
        }

API控制器示例

/// <summary>
/// Lockbox APIs
/// </summary>
[Route("api/v1/lockboxes"), ApiController]
public class LockboxController : ControllerBase
{ ...

    [HttpGet]
    public async Task<IActionResult> GetAll()
    {
        var lockboxes = await _lockboxService.GetAll();
        return Ok(lockboxes);
    }

排查与修复建议

1. 修正中间件执行顺序

.NET 6对中间件顺序有严格依赖,当前Startup.Configure中的顺序存在两处关键错误:

  • UseAuthentication必须在UseAuthorization之前执行,否则授权逻辑无法获取认证信息
  • UseCors必须放在UseRouting之后、UseEndpoints之前,否则跨域策略无法正确绑定到路由端点

调整后的正确顺序示例:

public void Configure(IApplicationBuilder app, IHostEnvironment env)
{                        
    app.UseHttpsRedirection();
    app.UseCurrentUser();
    app.UseMiddleware<ErrorHandlingMiddleware>();
    app.UseMiddleware<ApiLoggingMiddleware>();
    app.UseStaticFiles();
    
    app.UseRouting();

    // 跨域中间件移至路由配置后
    if (env.IsDevelopment())
    {
        app.UseCors(x => x.WithOrigins("http://localhost:8000", "http://localhost:3000").AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("File-Name").AllowCredentials());
    } 
    else
    {
        app.UseCors(MyAllowSpecificOrigins);
    }

    // 先认证再授权
    app.UseAuthentication();
    app.UseAuthorization();

    app.Use(async (ctx, next) =>
    {
        ctx.Response.Headers.Add("Content-Security-Policy",
                                 "default-src 'self';");
        await next();
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });

    // 统一管理环境相关配置
    if (!env.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
    else
    {
        app.UseDeveloperExceptionPage();
    }
}

2. 移除Program.cs中的重复配置

当前Program.cs在startup.Configure之后又添加了生产环境的异常处理和HSTS配置,会导致中间件链顺序混乱。建议将这部分逻辑移至Startup.Configure中统一管理,删除Program.cs中的以下代码:

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

3. 验证端点路由注册

  • 启动API时,查看控制台输出的路由映射日志(确保启用日志级别为Information),确认api/v1/lockboxes等端点是否被正确注册
  • 若后续启用Swagger,访问/swagger页面查看API端点是否正常显示,直接在Swagger中测试请求,排除前端请求路径或方式的问题

4. 排查HTTPS重定向影响

如果前端使用HTTP协议请求,而API启用了UseHttpsRedirection,可能导致301重定向后请求路径丢失。可在开发环境暂时注释app.UseHttpsRedirection()测试,或确保前端使用HTTPS协议请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:22:07