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:
- 自定义转换器类
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("此转换器仅支持反序列化"); } }
- 在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
相关产品推荐
相关产品推荐

