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

Json.NET在编辑器正常运行,打包后反序列化报错求助

问题解决:JSON反序列化为Dictionary打包报错的修复

错误原因

你遇到的JsonSerializationException是因为JSON中factionRelations是数组格式([]包裹的Key-Value对象列表),但C#的Dictionary<TKey, TValue>对应的标准JSON格式是对象格式({}包裹的键值对)。编辑器环境下可能因序列化兼容策略允许这种非标准转换,但打包后Newtonsoft.Json的严格校验会触发错误。

解决方案

方案1:修改JSON格式为标准Dictionary格式(推荐)

直接将JSON中的factionRelations从数组改为对象结构,这是最简洁且不易出问题的方式:

修改前的JSON片段:

"factionRelations": [
  {
    "Key": "Enemy",
    "Value": -100
  },
  {
    "Key": "Orbicom",
    "Value": 0
  }
]

修改后的JSON片段:

"factionRelations": {
  "Enemy": -100,
  "Orbicom": 0,
  "BodzanovaCo": 0
}

修改后无需改动C#代码,原有的JsonConvert.DeserializeObject<List<Faction>>即可正常工作。

方案2:使用自定义JsonConverter兼容现有JSON格式

如果无法修改JSON文件,可以给factionRelations字段添加自定义转换器,让Newtonsoft.Json能将Key-Value数组转换为Dictionary:

  1. 自定义转换器类
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Reflection;

public class KeyValueArrayToDictionaryConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Dictionary<,>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var keyType = objectType.GetGenericArguments()[0];
        var valueType = objectType.GetGenericArguments()[1];
        var kvpList = JArray.Load(reader).ToObject(typeof(List<KeyValuePair<,>>).MakeGenericType(keyType, valueType));
        
        var dictionary = Activator.CreateInstance(objectType);
        var addMethod = objectType.GetMethod("Add", new[] { keyType, valueType });
        
        foreach (var kvp in (IEnumerable)kvpList)
        {
            var key = kvp.GetType().GetProperty("Key").GetValue(kvp);
            var value = kvp.GetType().GetProperty("Value").GetValue(kvp);
            addMethod.Invoke(dictionary, new[] { key, value });
        }
        
        return dictionary;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException("此转换器仅支持反序列化");
    }
}
  1. 在Faction类的字段上添加转换器标记
[System.Serializable]
public class Faction
{
    public string name;
    public FactionType factionType;
    [JsonConverter(typeof(KeyValueArrayToDictionaryConverter))]
    public Dictionary<FactionType, int> factionRelations;
}

这样即使JSON保持原有数组格式,打包后也能正常反序列化为Dictionary。

额外注意事项

  • 确保FactionType是枚举类型,Newtonsoft.Json默认支持将字符串转换为枚举值,如果遇到枚举转换问题,可以给factionType字段添加[JsonConverter(typeof(StringEnumConverter))]标记。
  • 打包时确认Newtonsoft.Json的dll已正确包含在构建中(Unity中通常通过Package Manager安装的Newtonsoft.Json会自动处理)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:25:32