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

C#反序列化嵌套JSON数组遇Null值及序列化异常求助

解决方案:正确读取JSON嵌套数组并避免序列化异常

问题根源

你的JSON里actions、reactions、legendary_actions、special_abilities是数组类型(用[]包裹),但你定义的C#类里把这些字段声明成了ActionList这类自定义对象类型,Newtonsoft.Json会尝试把JSON数组当成对象反序列化,所以抛出异常;之前的null值也是因为类结构和JSON不匹配,无法正确映射数组数据。

步骤1:修正C#类定义

把原来的自定义列表类(比如ActionList)直接替换成List<T>类型,确保和JSON数组结构对应。示例如下:

原错误类结构(简化版)

public class MonsterOld
{
    // 错误:用自定义对象对应JSON数组
    public ActionList actions { get; set; }
    public SpecialAbilityList special_abilities { get; set; }

    public class ActionList
    {
        public List<Action> Actions { get; set; }
    }

    public class SpecialAbilityList
    {
        public List<SpecialAbility> SpecialAbilities { get; set; }
    }
}

修正后的类结构

using System.Collections.Generic;
using Newtonsoft.Json;

// 主类:直接用List<T>对应JSON里的数组字段
public class MonsterOld
{
    public string name { get; set; }
    public int hit_points { get; set; }
    // 直接用List<Action>匹配JSON数组
    public List<Action> actions { get; set; }
    public List<Reaction> reactions { get; set; }
    public List<LegendaryAction> legendary_actions { get; set; }
    public List<SpecialAbility> special_abilities { get; set; }
}

// 嵌套数组的子元素类:属性和JSON字段一一对应
public class Action
{
    public string name { get; set; }
    public string desc { get; set; }
    public int attack_bonus { get; set; }
    // 其他JSON里有的属性都加上
}

public class SpecialAbility
{
    public string name { get; set; }
    public string desc { get; set; }
}

public class Reaction
{
    public string name { get; set; }
    public string desc { get; set; }
}

public class LegendaryAction
{
    public string name { get; set; }
    public string desc { get; set; }
}

如果JSON字段和C#属性名大小写不匹配(比如JSON是action_name,C#是ActionName),可以用[JsonProperty]特性强制绑定:

public class Action
{
    [JsonProperty("action_name")]
    public string ActionName { get; set; }
}

步骤2:正确反序列化JSON

类结构修正后,用Newtonsoft.Json的反序列化方法就能正确读取嵌套数组,不会再报错:

// 读取JSON文件内容
string jsonContent = File.ReadAllText("your-monster-file.json");
// 反序列化到修正后的MonsterOld类
MonsterOld monster = JsonConvert.DeserializeObject<MonsterOld>(jsonContent);

此时monster.actions、monster.special_abilities等字段会正确加载数组数据,不会是null(如果JSON里对应数组存在的话)。

步骤3:转换为后续项目需要的格式

假设你需要把MonsterOld转换成MonsterNew类型,直接遍历嵌套数组即可,注意用?.处理可能的null值(避免空引用异常):

public MonsterNew ConvertToTargetFormat(MonsterOld oldMonster)
{
    if (oldMonster == null) return null;

    return new MonsterNew
    {
        MonsterName = oldMonster.name,
        HitPoints = oldMonster.hit_points,
        // 转换actions数组
        Actions = oldMonster.actions?.Select(a => new ActionNew
        {
            Name = a.name,
            Description = a.desc,
            AttackBonus = a.attack_bonus
        }).ToList(),
        // 同理转换其他嵌套数组
        SpecialAbilities = oldMonster.special_abilities?.Select(sa => new SpecialAbilityNew
        {
            AbilityName = sa.name,
            AbilityDesc = sa.desc
        }).ToList()
    };
}

// 后续项目用的目标类示例
public class MonsterNew
{
    public string MonsterName { get; set; }
    public int HitPoints { get; set; }
    public List<ActionNew> Actions { get; set; }
    public List<SpecialAbilityNew> SpecialAbilities { get; set; }
}

public class ActionNew
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int AttackBonus { get; set; }
}

关键注意事项

  • 始终保持C#类结构和JSON结构严格对应:JSON是数组用List<T>/T[],JSON是对象用自定义类。
  • 反序列化后先检查主对象是否为null,再访问嵌套字段。
  • 如果JSON里可能存在空数组或缺失字段,用?.运算符安全访问,避免程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:55:29