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

自定义ReferenceResolver反序列化时JSON引用丢失问题排查

自定义ReferenceResolver反序列化$ref无效问题

按照微软官方文档实现了自定义ReferenceResolver,序列化时JSON中的$id和$ref可正常生成,但反序列化时$ref无法被解析。

自定义Resolver代码

public class JsonReferenceResolver : ReferenceResolver
{
    private uint _referenceCount;
    private readonly Dictionary<string, object> _referenceIdToObjectMap = new();
    private readonly Dictionary<object, string> _objectToReferenceIdMap = new(ReferenceEqualityComparer.Instance);

    public override void AddReference(string referenceId, object value)
    {
        Console.WriteLine("Add Ref: " + referenceId);
        if (!_referenceIdToObjectMap.TryAdd(referenceId, value))
        {
            throw new JsonException();
        }
    }

    public override string GetReference(object value, out bool alreadyExists)
    {
        Console.WriteLine("Get Ref: " + value);

        if (_objectToReferenceIdMap.TryGetValue(value, out string? referenceId))
        {
            alreadyExists = true;
        }
        else
        {
            _referenceCount++;
            referenceId = _referenceCount.ToString();
            _objectToReferenceIdMap.Add(value, referenceId);
            alreadyExists = false;
        }

        return referenceId;
    }

    public override object ResolveReference(string referenceId)
    {
        Console.WriteLine("Res Ref: " + referenceId);
        if (!_referenceIdToObjectMap.TryGetValue(referenceId, out object? value))
        {
            throw new JsonException();
        }

        return value;
    }
}

自定义ReferenceHandler代码

public class JsonReferenceHandler : ReferenceHandler
{
    public JsonReferenceHandler() => Reset();
    private ReferenceResolver? _rootedResolver;
    public override ReferenceResolver CreateResolver() => _rootedResolver!;
    public void Reset(){
        _rootedResolver = new JsonReferenceResolver();
  }
}

JsonSerializerOptions配置

private static ReferenceHandler referenceHandler = new JsonReferenceHandler();

private static readonly JsonSerializerOptions options = new()
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    WriteIndented = true,
    ReferenceHandler = referenceHandler,
    IncludeFields = true
};

序列化与反序列化代码

序列化代码:

JsonSerializer.SerializeToNode(objectToSave, options);

反序列化代码:

JsonSerializer.Deserialize(typeconfigstring, options)

调试输出现象

  • GetReference:序列化时被调用
  • AddReference:反序列化时被调用,但并非JSON中的所有$id都会触发
  • ResolveReference:从未被调用

请问我是否哪里实现错误?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:43:17