C# JsonSerializer反序列化int返回0/null及嵌套JSON映射异常问题
问题根源
两个问题均为模型定义、序列化配置和JSON结构不匹配导致,无复杂逻辑问题:
- int类型属性始终返回0:System.Text.Json默认反序列化时属性名大小写严格匹配,你的
basictest类中contact属性是小写c开头,JSON中对应键是大写C开头的Contact,匹配失败后int类型会被赋值默认值0。同理嵌套类中的Address、PhoneNumbers属性是大写开头,JSON中对应键是小写开头的address、phoneNumbers,同样会匹配失败返回null。 - 嵌套结构读取异常:JSON中的
phoneNumbers是数组结构(用[]包裹,即使仅存1个元素),但你的C#模型中将其定义为单个phoneNumbers类实例,类型不匹配直接导致反序列化失败。
修复方案
推荐使用第一种方案,代码改动最小:
方案1:开启大小写不敏感匹配,修正模型类型
- 反序列化时传入配置,全局开启属性名大小写不敏感匹配
- 将
nestedtest类中的PhoneNumbers属性改为集合类型,对应JSON的数组结构
修正后的核心代码如下:
首先调整类定义:
public class basictest { public string Name { get; set; } public int Contact { get; set; } } public class nestedtest { public string firstName { get; set; } public string lastName { get; set; } public int age { get; set; } public address address { get; set; } // 改为List类型匹配JSON数组结构 public List<phoneNumbers> phoneNumbers { get; set; } } public class address { public string streetAddress { get; set; } public string city { get; set; } public string state { get; set; } public string postalCode { get; set; } } public class phoneNumbers { public string type { get; set; } public string number { get; set; } }
再修改反序列化调用逻辑,传入序列化配置:
// 定义全局序列化配置即可,无需每次重复声明 private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; private void deserial_Click(object sender, EventArgs e) { string jsonString = File.ReadAllText(basicjson); basictest BasicJson = JsonSerializer.Deserialize<basictest>(jsonString, _jsonOptions); label1.Text = BasicJson.Contact.ToString(); listBox1.Items.Add(BasicJson.Contact); textBox1.Text = BasicJson.Contact.ToString(); } private void deserialnested_Click(object sender, EventArgs e) { string jsonString = File.ReadAllText(nestedjson); nestedtest nestedJson = JsonSerializer.Deserialize<nestedtest>(jsonString, _jsonOptions); // phoneNumbers现在是集合,取第一个元素即可 listBox1.Items.Add(nestedJson.phoneNumbers[0].type); }
方案2:用特性显式映射JSON键名
如果不想开启全局大小写不敏感匹配,可以给每个属性加JsonPropertyName特性,显式标注对应的JSON键名,示例:
public class basictest { [JsonPropertyName("Name")] public string Name { get; set; } [JsonPropertyName("Contact")] public int contact { get; set; } }
这种方式适合属性名和JSON键名差异较大的场景,当前场景直接开启大小写不敏感即可满足需求。
验证说明
改完后可断点查看反序列化结果:
- 基础JSON反序列化后
Contact属性正常获取12345678,不会再返回默认值0 - 嵌套JSON反序列化后
address字段可正常读取街道、城市等值,phoneNumbers是长度为1的集合,首个元素的type值为home
额外提示:JSON中多出的
gender字段不会影响反序列化,System.Text.Json默认会自动忽略模型中无对应属性的键,无需额外处理。
内容的提问来源于stack exchange,提问作者TheTripleDeuce
相关产品推荐
相关产品推荐

