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

如何在System.Text.Json中使用JsonConstructor特性解决反序列化报错

问题原因

首次报错原因

最初的JSON外层使用{}包裹,属于JSON对象结构,而你尝试反序列化为List<AbilityTemplate>数组类型,二者结构不匹配导致反序列化失败,后续将外层改为[]的操作是正确的。

二次报错原因

有三个核心问题共同触发异常:

  • 构造函数参数与属性映射不匹配:System.Text.Json要求带[JsonConstructor]标记的构造函数的每个参数,必须对应到类的一个公共属性/字段,匹配规则默认区分大小写。你的JSON使用小驼峰命名(如id),如果类属性是帕斯卡命名(如Id),默认会匹配失败。
  • 字符串数字无法自动转数值类型:JSON里price、size都是带引号的字符串格式,而构造函数对应参数是int类型,System.Text.Json默认不会自动将字符串数字转为数值类型。
  • 枚举默认不支持字符串反序列化:Rarity是枚举类型,默认System.Text.Json只能反序列化数字格式的枚举值,你JSON里是字符串格式的枚举名,没有配置对应转换器的情况下会反序列化失败。
解决方法
  1. 配置反序列化参数:在调用Deserialize方法时传入JsonSerializerOptions,开启所需的配置:
var jsonOptions = new JsonSerializerOptions
{
    // 允许不区分大小写匹配属性名,兼容小驼峰JSON和帕斯卡类属性
    PropertyNameCaseInsensitive = true,
    // 允许从字符串读取数字,解决JSON字符串数字转int的问题
    NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString,
    // 添加枚举字符串转换器,支持字符串转枚举
    Converters = { new JsonStringEnumConverter() }
};

如果不想全局开启不区分大小写匹配,也可以给每个属性添加[JsonPropertyName]特性显式指定JSON对应的键名,示例:

public class AbilityTemplate
{
    [JsonPropertyName("id")]
    public string Id { get; }
    [JsonPropertyName("price")]
    public int Price { get; }
    // 其余属性同理配置
}
  1. 确认类属性可访问性:确保AbilityTemplate的所有对应属性(Id、Price、Size、Rarity、AbilityEffectFactory)为公共属性,如果属性为私有需要额外添加[JsonInclude]标记。
  2. 修改反序列化代码:将配置传入反序列化方法即可:
string text = File.ReadAllText(Path.Combine(EntityDirectory, @"Json\AbilityTemplates.json"));
foreach (AbilityTemplate template in JsonSerializer.Deserialize<List<AbilityTemplate>>(text, jsonOptions)) 
{
    loaderInterface.AddAbilityTemplate(template);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:06:04