如何修复JsonConverter的“无法解析原始值”错误?
问题分析与解决方案
核心问题原因
- WriteValue导致反斜杠的原因:你用
WriteValue(JsonConvert.SerializeObject(value))时,是把value序列化后的JSON字符串作为普通字符串写入JSON,Json.NET会自动转义字符串里的双引号等特殊字符,所以出现大量反斜杠——本质是把JSON对象打包成了字符串值,而非直接写入JSON结构。 - WriteRawValue导致读取失败的原因:改用
WriteRawValue后,是直接把序列化后的JSON对象内容嵌入当前位置,此时JSON结构里这部分是嵌套对象,不是字符串。所以ReadJson时reader的TokenType是JsonToken.StartObject,而非字符串类型,自然reader.Value为null,调用reader.Value.ToString()就会报错。
正确的实现方式
1. 修复WriteJson方法(生成无转义的干净JSON)
不要用JsonConvert.SerializeObject二次序列化,直接利用传入的serializer处理value的属性,同时通过skipOverMe避免递归调用当前Converter:
public override void WriteJson(JsonWriter writer, ManagedSubData value, JsonSerializer serializer) { skipOverMe = true; value.GrabAssetPath(); // 直接序列化value为原生JSON对象,无多余转义 JObject obj = JObject.FromObject(value, serializer); obj.WriteTo(writer); skipOverMe = false; }
或者更简洁的写法:
public override void WriteJson(JsonWriter writer, ManagedSubData value, JsonSerializer serializer) { skipOverMe = true; value.GrabAssetPath(); serializer.Serialize(writer, value); skipOverMe = false; }
这样生成的JSON是正常的嵌套结构,可读性强且无多余反斜杠。
2. 修复ReadJson方法(适配正确的读取逻辑)
既然写入的是JSON对象,读取时直接从reader加载整个JObject,不需要依赖reader.Value:
public override ManagedSubData ReadJson(JsonReader reader, Type objectType, ManagedSubData existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return null; } // 直接从reader加载JObject,而非解析reader.Value JObject obj = JObject.Load(reader); ManagedSubData asset = ManagedDataHandler.GetSubDataFromGUID(obj["GUID"].ToString()); if (asset == null) { asset = ScriptableObject.CreateInstance(objectType) as ManagedSubData; #if UNITY_EDITOR if (!Application.isPlaying) { AssetDatabase.CreateAsset(asset, obj["assetPath"].ToString()); AssetDatabase.SaveAssets(); } #endif } if (!asset.KeepPlayModeChanges) { // 用JObject填充对象,避免重复读取无效的reader.Value obj.Populate(asset); asset.SetDirty(); } return asset; }
关键说明
- 嵌套层级下,WriteValue添加的反斜杠不是解析必需的,那只是把JSON对象转成字符串值的产物,正常的JSON嵌套应该直接写入对象结构,不需要转义。
- 自定义Converter里应避免用
JsonConvert.SerializeObject二次序列化,这会触发递归调用还会导致不必要的字符串转义,直接利用传入的serializer处理序列化/反序列化逻辑才是正确做法。
内容的提问来源于stack exchange,提问作者Steven Goulet
相关产品推荐
相关产品推荐

