.NET Core Web API返回CommonApiResponse时Content始终为空数组问题
我有一个.NET Core Web API端点,返回如下定义的CommonApiResponse类:
public class CommonApiResponse { public bool Success { get; set; } = true; public string Message { get; set; } = "Sucess"; public object? Content { get; set; } }
编写了如下方法获取动态JSON数据:
public async Task<CommonApiResponse> GetMasterDataPost(MasterDataApiModel param) { var result = new CommonApiResponse(); try { var masterData = await MasterDataAPI.GetMasterDataPost(param); // example: [{"PLANT":2100},{"PLANT":2200},{"PLANT":2210},{"PLANT":2300},{"PLANT":2310},{"PLANT":2320},{"PLANT":2400},{"PLANT":2600},{"PLANT":3100},{"PLANT":3300},{"PLANT":4200},{"PLANT":8000}] JArray jsonResponse = JArray.Parse(masterData); result.Content = jsonResponse; } catch { throw; } return result; }
JArray解析后的内容包含有效数据,但通过如下端点返回给客户端时:
[HttpPost("GetMasterDataPost")] public async Task<IActionResult> GetMasterDataPost(MasterDataApiModel param) { var result = await _masterDataBusiness.GetMasterDataPost(param); return Ok(result); }
Content始终仅返回空数组[]。尝试改用dynamic jsonResponse = JsonConvert.DeserializeObject(masterData);进行反序列化,以及将CommonApiResponse类的Content属性改为dynamic类型,均无法解决问题,请问可能的原因是什么?
序列化库冲突
.NET Core默认使用System.Text.Json做序列化,而JArray是Newtonsoft.Json(Json.NET)的专属类型。System.Text.Json无法识别JArray的内部数据结构,序列化时只会输出空数组。哪怕用JsonConvert.DeserializeObject得到的dynamic,本质还是Newtonsoft的JObject/JArray,同样会被System.Text.Json错误处理。解决办法1:统一用Newtonsoft.Json序列化
替换Web API默认的序列化库为Newtonsoft.Json:- 安装NuGet包
Microsoft.AspNetCore.Mvc.NewtonsoftJson - 在
Program.cs中配置:
builder.Services.AddControllers() .AddNewtonsoftJson();这样序列化
JArray或Newtonsoft的动态类型时,就能正确输出数据。- 安装NuGet包
解决办法2:转换为System.Text.Json支持的类型
不要直接返回JArray,转成List<dynamic>或字典列表让默认序列化库识别:// 替换原JArray赋值代码 result.Content = jsonResponse.ToObject<List<dynamic>>();或者直接用Newtonsoft反序列化为通用集合:
result.Content = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(masterData);解决办法3:改用JsonElement作为Content类型
使用System.Text.Json的JsonElement存储动态JSON内容,兼容性更强:- 修改
CommonApiResponse类:
public class CommonApiResponse { public bool Success { get; set; } = true; public string Message { get; set; } = "Sucess"; public JsonElement? Content { get; set; } }- 解析时用
System.Text.Json处理:
using var doc = JsonDocument.Parse(masterData); result.Content = doc.RootElement.Clone();- 修改
内容的提问来源于stack exchange,提问作者kbdev

