You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

System.Text.Json反序列化时数组属性未映射问题排查

System.Text.Json反序列化字段为空/无法映射的问题解决

问题重现

Web服务返回的JSON结构(简化版):

{
   "totalSize":401,
   "pageSize":250,
   "totalPages":2,
   "currentPage":1,
   "version":{
      "obsoleteDate":null,
      "resourceVersion":"2021-03-29"
   },
   "messages":[{},{}],
   "_embedded":[{"id": "dfsdf"}]
}

定义的泛型响应类:

public class PagedResponse<T>
{
    public int TotalSize { get; set; } = 0;
    public int PageSize { get; set; } = 0;
    public int TotalPages { get; set; } = 0;

    [JsonPropertyName("currentPage")]
    public int CurrentPage { get; set; } = 0;

    [JsonPropertyName("version")]
    public Version Version { get; set; } = new Version();

    [JsonPropertyName("messages")]
    public List<Message> Messages = new List<Message> { };

    [JsonPropertyName("_embedded")]
    [JsonProperty(PropertyName = "_embedded")]
    public List<T> Embedded = new List<T>();

    public PagedResponse() { }
}

使用System.Text.Json反序列化时:

PagedResponse<Employee>? response = await dataResponse.Content.ReadFromJsonAsync<PagedResponse<Employee>>(new JsonSerializerOptions() { 
    PropertyNameCaseInsensitive = true
});

出现以下问题:

  • Messages和Embedded始终为空列表
  • 开启UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow时,会提示messages字段无法映射

但使用Newtonsoft.Json的JsonConvert反序列化时一切正常。

问题原因

Newtonsoft.Json默认会处理字段和属性,而System.Text.Json的默认行为是仅处理带get/set访问器的属性。你的代码中Messages和Embedded是直接定义的公共字段(没有get; set;),所以System.Text.Json在反序列化时会忽略这些成员,导致无法映射JSON中的对应数据。

解决方案

方案1:将字段改为属性(推荐)

遵循C#编码规范,把公共字段改为自动属性,这样既能兼容Newtonsoft.Json也能正常被System.Text.Json处理:

public class PagedResponse<T>
{
    // ... 其他属性保持不变 ...

    [JsonPropertyName("messages")]
    public List<Message> Messages { get; set; } = new List<Message>();

    [JsonPropertyName("_embedded")]
    [JsonProperty(PropertyName = "_embedded")] // 保留Newtonsoft的特性以兼容旧代码
    public List<T> Embedded { get; set; } = new List<T>();

    public PagedResponse() { }
}

方案2:配置System.Text.Json支持字段

如果无法修改类的定义,可以在JsonSerializerOptions中开启字段支持:

PagedResponse<Employee>? response = await dataResponse.Content.ReadFromJsonAsync<PagedResponse<Employee>>(new JsonSerializerOptions() { 
    PropertyNameCaseInsensitive = true,
    IncludeFields = true // 启用字段的序列化/反序列化支持
});

注意:方案1更符合C#的设计规范,字段通常作为类的内部成员使用,对外暴露数据优先使用属性;方案2适合需要兼容现有字段定义的场景。

内容的提问来源于stack exchange,提问作者zu1b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:45:21