调用受保护ASP.NET Core 5 Web API返回HTTP 406错误如何解决?
排查方向
- 检查API端服务注册冲突
当前同时注册了services.AddMvc()与services.AddControllers(),.NET 5中AddMvc()会默认引入全量MVC组件,包括Razor页面相关的输出格式化器,可能篡改了JSON格式化器的优先级。Web API场景无需完整MVC功能,可以直接删除services.AddMvc()注册,仅保留services.AddControllers()即可。 - 排查自定义JSON转换器异常
配置的DateTimeConverter如果在序列化返回数据时抛出未捕获的异常,ASP.NET Core框架无法找到可用的输出格式,也会返回406错误。可以临时注释掉该转换器的注册,验证是否是序列化异常导致的问题。 - 验证MVC端实际请求头
虽然代码中指定了Accept为application/json,但需要确认实际发出的请求头是否符合预期:可以通过抓包工具(Fiddler、Charles等)查看实际请求的Accept头是否携带其它格式,或者是否有q值优先级高于JSON的格式配置;同时确认Authorization头的token是否有效,部分中间件拦截异常响应时也可能导致格式不匹配。 - 显式指定API端输出格式化器
可以在控制器配置中关闭内容协商、强制保留仅JSON格式化器,避免其它格式化器干扰:
services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new DateTimeConverter()); }) .AddMvcOptions(options => { // 关闭内容协商,不匹配Accept头时直接返回默认格式 options.RespectBrowserAcceptHeader = false; options.ReturnHttpNotAcceptable = false; // 移除非JSON的输出格式化器 options.OutputFormatters.RemoveType<StringOutputFormatter>(); options.OutputFormatters.RemoveType<StreamOutputFormatter>(); // 确保JSON格式化器优先级最高 options.OutputFormatters.Insert(0, new SystemTextJsonOutputFormatter(options.JsonSerializerOptions)); });
- 检查控制器特性覆盖
确认基类MyBaseController上是否标注了其它[Produces]特性,覆盖了子类的[Produces("application/json")]配置,可以直接在具体Action方法上再加一次[Produces("application/json")]做验证。 - 验证请求路由是否命中预期端点
在API接口方法内加断点或日志,确认MVC端的请求是否真的命中了目标接口,若路由匹配错误落到了其它没有配置JSON输出的端点上,也会返回406错误。
内容的提问来源于stack exchange,提问作者marc_s
相关产品推荐
相关产品推荐

