C# JSON反序列化返回空对象列表问题求助
嘿,我之前也碰到过一模一样的问题!这种情况大概率是实体类和JSON字段不匹配或者序列化配置的问题,给你列几个最常见的排查方向:
C#默认用PascalCase命名(比如Amount),但很多JSON会用camelCase(比如amount)或者snake_case(比如transaction_amount),这时候序列化器找不到对应字段,就会给属性赋默认值(数字0、字符串空)。
解决方法有两种:
- 给实体类属性加匹配特性:
// 如果你用System.Text.Json public class Transaction { [JsonPropertyName("amount")] public decimal Amount { get; set; } [JsonPropertyName("description")] public string Description { get; set; } } // 如果你用Newtonsoft.Json(Json.NET) public class Transaction { [JsonProperty("amount")] public decimal Amount { get; set; } [JsonProperty("description")] public string Description { get; set; } } - 或者配置序列化器忽略大小写(适合字段名只是大小写差异的情况):
// System.Text.Json写法 var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var transactionList = JsonSerializer.Deserialize<List<Transaction>>(jsonContent, options);
如果你的属性是private/protected,或者只有get没有set,序列化器无法给属性赋值,自然会用默认值。
❌ 错误示例:
public class Transaction { // 只有get,序列化器无法写入值 public decimal Amount { get; } // 私有属性,序列化器无权访问 private string Description { get; set; } }
✅ 正确写法:确保属性是public且同时有get和set:
public class Transaction { public decimal Amount { get; set; } public string Description { get; set; } }
比如你的JSON数组外面还套了一层包装对象,但你直接反序列化成List<T>,这时候肯定拿不到数据。
举个例子,如果你的JSON是这样的:
{ "code": 200, "data": [ {"amount": 150, "description": "餐饮"}, {"amount": 3000, "description": "房租"} ] }
你不能直接反序列化成List<Transaction>,得先创建一个包装类:
public class TransactionResponse { [JsonPropertyName("data")] public List<Transaction> Transactions { get; set; } }
然后再反序列化:
var response = JsonSerializer.Deserialize<TransactionResponse>(jsonContent); var transactionList = response.Transactions;
比如你给实体类加了Newtonsoft的[JsonProperty]特性,却用System.Text.Json的JsonSerializer.Deserialize来反序列化,这时候特性完全不生效,自然匹配不上字段。
解决方法:保持序列化库一致——要么全用System.Text.Json(.NET Core 3.0+内置),要么全用Newtonsoft.Json(需要NuGet安装)。
比如JSON里的amount是字符串类型("amount": "200"),但你的实体类里是decimal,这时候序列化器无法自动转换,就会给0值。
解决方法:
- 要么修改实体类属性类型为
string,之后手动转换为数字; - 要么配置序列化器允许类型转换:
// System.Text.Json写法 var options = new JsonSerializerOptions { NumberHandling = JsonNumberHandling.AllowReadingFromString }; var transactionList = JsonSerializer.Deserialize<List<Transaction>>(jsonContent, options);
最后给个小技巧:如果不确定哪里错了,可以用在线工具(比如JSON2Csharp)把你的JSON直接转换成实体类,对比一下自己写的类哪里不一样,大概率能找到问题!
内容的提问来源于stack exchange,提问作者Xabi




