.NET 8微服务:反序列化WebApi返回的ProblemDetails失败求助
问题分析与解决方案
这不是正常行为,问题出在WebApiOne中IExceptionHandler的实现逻辑上:你的代码直接向Response写入了ProblemDetails,但没有正确通知ASP.NET Core框架异常已被完全处理,导致框架后续自动添加了一层包含problemDetails、contentType、statusCode的包装结构,最终返回的JSON不是你预期的纯ProblemDetails对象。
解决方法一:修正WebApiOne的异常处理器(推荐)
修改GlobalHandler的实现,确保处理完异常后返回true,终止框架的后续处理流程,同时修正errors字段的嵌套问题(原代码会生成二维数组,不符合返回的JSON结构):
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken) { // 替换为你实际的状态码、标题、错误信息、TraceId获取逻辑 var statusCode = StatusCodes.Status404NotFound; var title = "Not Found"; var errors = new[] { "Company xxxxx not found." }; var traceId = Activity.Current?.Id ?? httpContext.TraceIdentifier; var problemDetails = new ProblemDetails { Status = statusCode, Title = title, Extensions = new Dictionary<string, object?> { // 移除多余的new[]包裹,直接使用一维数组 { "errors", errors?.ToArray() }, { "traceId", traceId } } }; httpContext.Response.StatusCode = statusCode; await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken); // 返回true告知框架异常已处理,无需后续操作 return true; }
修改后,WebApiOne会直接返回纯ProblemDetails结构的JSON,WebApiTwo原有的反序列化代码即可正常工作。
解决方法二:调整WebApiTwo的反序列化逻辑(临时方案)
如果暂时无法修改WebApiOne的代码,可以在WebApiTwo中先解析外层的包装对象,再提取内部的ProblemDetails:
- 定义包装类:
public class ProblemDetailsWrapper { public ProblemDetails ProblemDetails { get; set; } public string ContentType { get; set; } public int StatusCode { get; set; } }
- 修改反序列化代码:
var wrapper = JsonConvert.DeserializeObject<ProblemDetailsWrapper>(response.Content); ProblemDetails problem = wrapper?.ProblemDetails;
内容的提问来源于stack exchange,提问作者kulwant
相关产品推荐
相关产品推荐

