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

如何修复JsonConverter的“无法解析原始值”错误?

问题分析与解决方案

核心问题原因

  1. WriteValue导致反斜杠的原因:你用WriteValue(JsonConvert.SerializeObject(value))时,是把value序列化后的JSON字符串作为普通字符串写入JSON,Json.NET会自动转义字符串里的双引号等特殊字符,所以出现大量反斜杠——本质是把JSON对象打包成了字符串值,而非直接写入JSON结构。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:53:19