Json.NET C#:在反序列化时将忽略在Custom Contract Resolver中分配的Custom Converter

时间:2018-08-21 16:34:28

标签: c# json.net deserialization contract resolver

我一直在构建一个序列化系统,该系统可以根据对象装饰的属性分配一个特殊的ReferenceJConverterDefinitionJConverter来工作。这些自定义JsonConverter由自定义ContractResolver中的逻辑分配,而不是采用更传统的技术来确定可以使用CanConvert函数进行转换的内容。自定义解析器会覆盖CreateProperty函数,如下所示:

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
    JsonProperty property = base.CreateProperty(member, memberSerialization);

    if (member is FieldInfo field)
    {
        // Does this field implement IList? This Utility function gets all member interfaces and checks if any of them equal the argued interface.
        if (field.FieldType.ImplementsInterface<IList>())
        {
            // Are the elements of this IList decorated with [Ref]?
            if (field.FieldType.GetGenericArguments()[0].HasAttribute<RefAttribute>())
            {
                // Does this collection field have [Def]?
                if (field.HasAttribute<DefAttribute>())
                {
                    // This is a collection of definitions.
                    property.Converter = new DefCollectionJConverter();
                }
                else
                {
                    // This is a collection of references.
                    property.Converter = new RefCollectionJConverter();
                }
            }
        }
        else
        {
            // If the field's type class has been decorated with Ref.
            if (field.FieldType.HasAttribute<RefAttribute>())
            {
                if (member.HasAttribute<DefAttribute>())
                {
                    // If this particular field also has Def, it's a definition.
                    property.Converter = new DefinitionJConverter();
                }
                else
                {
                    // Else it's a reference.
                    property.Converter = new ReferenceJConverter();
                }
            }
        }
    }

    return property;
}

如您所见,它还可以处理集合,但我目前尚未对此进行测试。

这些自定义转换器要么按常规方式序列化对象(如果已定义),要么将其序列化为数字或清晰的字符串名(如果是引用)。

令人讨厌的是,序列化工作正常。我得到了想要的Json输出:

{
  "wineofTheDayRef": "Merlot_WIN",
  "wineOfTheDay": {
    "tag": {
      "literalTag": "Merlot_WIN"
    },
  },
}

反序列化会中断。 Json.NET似乎在CreateProperty中循环并分配了所有正确的转换器,但是似乎从未调用过这些转换器。相反,我得到了:

Newtonsoft.Json.JsonSerializationException : Error converting value "Merlot_WIN" to type 'OrthrusStudios.Serialisation.PirateExample.Wine'. Path 'wineofTheDayRef', line 2, position 33.

----> System.ArgumentException:无法将System.String强制转换或转换为OrthrusStudios.Serialisation.Examples.Wine。

...警告我,参考字符串“ Merlot_WIN”无法转换为类型“ Wine”;我有一个自定义转换器,可以做到这一点,只需通过按其字符串名称查找反序列化的对象,或者如果尚未反序列化其定义,就向该对象发出请求。为什么我的代码甚至到达这里?

在我改用ContractResolver方法之前,我的自定义转换器工作得很好。从理论上讲,逻辑不应该相同吗?

错误来自JsonSerializerInternalReader.EnsureType()

0 个答案:

没有答案