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
相关产品推荐
相关产品推荐

