.NET6 Core Web API错误返回XML而非JSON的解决求助
解决.NET6 Core Web API 严格分离JSON/XML返回格式(含异常场景)
一、基础配置(保留双格式化器)
先确保Program.cs中已正确启用Newtonsoft JSON和XML序列化支持:
builder.Services.AddControllers() .AddNewtonsoftJson() // 启用Newtonsoft JSON处理 .AddXmlSerializerFormatters(); // 启用XML序列化
二、给接口强制绑定输出格式
通过[Produces]特性为每个接口固定返回格式,同时用[Consumes]限制输入类型,确保接口职责严格分离:
JSON专用接口
[ApiController] [Route("api")] public class FormatController : ControllerBase { // 仅接受JSON输入,强制返回JSON [HttpPost("json")] [Produces("application/json")] [Consumes("application/json")] public IActionResult JsonPost([FromBody] JsonRequestModel model) { // 业务逻辑示例 return Ok(new { Result = "JSON请求处理完成" }); } }
XML专用接口
// 仅接受XML输入,强制返回XML [HttpPost("xml")] [Produces("application/xml")] [Consumes("application/xml")] public IActionResult XmlPost([FromBody] XmlRequestModel model) { // 业务逻辑示例 return Ok(new XmlResponseModel { Result = "XML请求处理完成" }); }
注意:XML序列化要求模型类必须有无参构造函数,属性需为公共可读写(可配合
[XmlElement]等特性自定义序列化规则)。
三、处理异常/验证错误场景
默认情况下,输入格式错误(如提交无效JSON到api/json)会触发模型验证失败,此时.NET会遍历格式化器列表选择第一个匹配项,导致错误返回XML。需通过自定义过滤器强制按接口指定格式返回错误:
1. 自定义异常过滤器(处理未捕获异常)
public class FormatLockedExceptionFilter : IExceptionFilter { private readonly ILogger<FormatLockedExceptionFilter> _logger; public FormatLockedExceptionFilter(ILogger<FormatLockedExceptionFilter> logger) { _logger = logger; } public void OnException(ExceptionContext context) { // 获取当前接口指定的输出格式 var producesAttr = context.ActionDescriptor.EndpointMetadata .OfType<ProducesAttribute>() .FirstOrDefault(); if (producesAttr?.ContentTypes.Any() == true) { var targetType = producesAttr.ContentTypes.First(); // 构造统一错误响应 context.Result = new ObjectResult(new { ErrorMsg = context.Exception.Message, StatusCode = StatusCodes.Status500InternalServerError }) { ContentTypes = new MediaTypeCollection { targetType }, StatusCode = StatusCodes.Status500InternalServerError }; context.ExceptionHandled = true; } _logger.LogError(context.Exception, "接口执行异常"); } }
2. 自定义模型验证过滤器(处理输入格式错误)
public class FormatLockedValidationFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { var producesAttr = context.ActionDescriptor.EndpointMetadata .OfType<ProducesAttribute>() .FirstOrDefault(); if (producesAttr?.ContentTypes.Any() == true) { var targetType = producesAttr.ContentTypes.First(); // 构造验证错误响应 var errors = context.ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage); context.Result = new BadRequestObjectResult(new { ValidationErrors = errors, StatusCode = StatusCodes.Status400BadRequest }) { ContentTypes = new MediaTypeCollection { targetType } }; } } } public void OnActionExecuted(ActionExecutedContext context) { } }
3. 注册过滤器到全局
在Program.cs的控制器配置中添加两个过滤器:
builder.Services.AddControllers(options => { options.Filters.Add<FormatLockedExceptionFilter>(); options.Filters.Add<FormatLockedValidationFilter>(); }) .AddNewtonsoftJson() .AddXmlSerializerFormatters();
四、验证效果
- 向
api/json提交无效JSON,返回的错误响应为application/json格式 - 向
api/xml提交无效XML,返回的错误响应为application/xml格式 - 正常请求时,两个接口分别返回对应格式的响应
内容的提问来源于stack exchange,提问作者Paja
相关产品推荐
相关产品推荐

