ASP.NET Core 3.1升级.NET6时Content-Type协商失效问题
问题产生原因
这是.NET 6对ProblemDetails响应处理逻辑的默认行为变更,未在通用迁移文档中单独标注:
- .NET Core 3.1 阶段没有为ProblemDetails响应提供专属输出格式化器,
Problem()方法返回的结果会作为普通对象走全局内容协商逻辑,严格遵守Action上[Produces]特性声明的响应格式,因此标注[Produces(MediaTypeNames.Application.Xml)]时会正常返回XML格式内容,Content-Type为application/xml。 - .NET 6 新增了专属的
ProblemDetailsOutputFormatter,该格式化器执行优先级高于通用对象输出格式化器,默认仅支持application/problem+json格式输出,不会自动遵循[Produces]特性声明的XML格式。当请求匹配到该格式化器时,会直接返回JSON格式的Problem响应,不会进入后续XML格式化器的协商流程,最终出现Content-Type不符合预期的问题。
修复方案
可根据实际场景选择以下任意一种方案:
方案1:接口级快速修复
直接在调用Problem()方法时显式指定contentType参数,强制当前接口返回XML格式的Problem结果,无需修改全局配置:
[HttpPost] [Produces(MediaTypeNames.Application.Xml)] [Consumes(MediaTypeNames.Application.Xml)] public IActionResult Xml() { // 显式指定响应Content-Type为application/xml return Problem(contentType: MediaTypeNames.Application.Xml); }
方案2:全局配置修复
如果需要所有标注[Produces(MediaTypeNames.Application.Xml)]的接口都自动返回XML格式的Problem结果,可以在服务注册阶段做全局配置:
- 注册XML序列化格式化器
- 给ProblemDetails专属输出格式化器添加对
application/xml媒体类型的支持
// .NET 6 顶级语句Program.cs示例 builder.Services.AddControllers() // 注册XML序列化格式化器 .AddXmlSerializerFormatters() .AddMvcOptions(options => { // 给ProblemDetails输出格式化器添加XML媒体类型支持 var problemFormatter = options.OutputFormatters .OfType<Microsoft.AspNetCore.Mvc.Formatters.ProblemDetailsOutputFormatter>() .FirstOrDefault(); if (problemFormatter != null) { problemFormatter.SupportedMediaTypes.Add(MediaTypeNames.Application.Xml); } });
如果你使用传统Startup类结构,把上述配置写在ConfigureServices方法内的AddControllers()调用链上即可。
如果你希望遵循RFC标准返回
application/problem+xml类型的Problem响应,只需要把上述配置里的媒体类型替换为application/problem+xml即可,不需要修改其他业务逻辑。
内容的提问来源于stack exchange,提问作者joacar
相关产品推荐
相关产品推荐

