.Net Core API接收OPTIONS请求返回500 AmbiguousMatchException问题问询
.NET Core API OPTIONS预检请求错误解决方案
核心问题原因
你的问题完全由配置错误导致,共4处关键问题:
- 中间件执行顺序错误:
UseCors放在了认证、授权中间件之后,OPTIONS预检请求不会携带认证信息,会被认证中间件直接拦截返回错误,根本不会走到CORS逻辑 - 自定义响应头中间件位置错误:你添加
Access-Control-Allow-Origin的自定义中间件放在UseEndpoints之后,请求走完路由逻辑就会直接返回,该中间件永远不会执行,反而会因为和CORS策略重复加头引发二次错误 - 服务重复注册:
AddControllers被重复注册了两次,虽不直接报错但属于冗余配置 - Kestrel监听配置冲突:你同时配置了
UseUrls绑定https地址,又在UseKestrel里监听http 5000端口,协议不统一会导致跨域协议不匹配
具体修改方案
1. 修改Program.cs(Web Host配置)
删除冲突的监听配置,统一端口协议:
public static IHostBuilder CreateWebHostBuilder(string[] args) { var host = Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<EngineAPI.Startup>(); // 统一使用http监听5000端口,https按需调整 webBuilder.UseUrls("http://127.0.0.1:5000"); }); return host; }
2. 修改Startup.cs配置
第一步:调整ConfigureServices的CORS配置
如果你使用Negotiate(Windows认证)需要携带凭证,不能使用*作为允许源,需要替换为实际的前端服务地址,示例:
public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(name: MyAllowSpecificOrigins, builder => { // 开发环境临时用*的话不能搭配AllowCredentials // 生产环境替换为实际前端地址,比如builder.WithOrigins("http://localhost:8080") builder.WithOrigins("*") .AllowAnyHeader() .AllowAnyMethod(); // 如果指定了具体源,需要带认证凭证的话加上这句:.AllowCredentials(); }); }); services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(); // 删除重复的AddControllers,保留一个即可 services.AddControllers(); }
第二步:调整Configure的中间件顺序
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); // 优先放CORS中间件,优先级高于认证授权 app.UseCors(MyAllowSpecificOrigins); // 认证在前,授权在后 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // 删除后面自定义加CORS头的中间件,完全冗余且会引发错误 }
修改完成后重启服务即可正常处理OPTIONS预检请求。
内容的提问来源于stack exchange,提问作者Boardy
相关产品推荐
相关产品推荐

