带有嵌套对象的JSON.NET CustomCreationConverter

 为了未来而奋斗2010 发布于 2023-02-12 16:36

这是我在这个网站上提出的第一个问题,如果我错过了什么,请原谅我.

我在使用JSON.NET反序列化复杂对象图时遇到了一些问题.我的类层次结构(简化)如下:

public abstract class BusinessObjectBase
{
    protected BusinessObjectBase(SerializationContext context)
    {
    }
}

public class TestBusinessObject : BusinessObjectBase
{
    protected TestBusinessObject(SerializationContext context)
        : base(context)
    {
    }

    public NestedObject InnerObject { get; set; }
}

public class NestedObject : BusinessObjectBase
{
    protected NestedObject(SerializationContext context)
        : base(context)
    {
    }
}

这些类没有默认的ctor,而是一个专用的自定义反序列化ctor(除了带参数的其他公共ctor),如示例所示.要创建一个实例,我编写了一个自定义创建转换器,如下所示:

internal class BusinessObjectCreationConverter : CustomCreationConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(BusinessObjectBase).IsAssignableFrom(objectType) && !objectType.IsAbstract;
    }

    public override BusinessObjectBase Create(Type objectType)
    {
        var businessObject = objectType.CreateUsingDesrializationConstructor();
        return businessObject;
    }
}

CreateUsingDesrializationConstructor()扩展方法查找特殊反序列化ctor并使用ctor创建实例.

我将转换器添加到我的JSON.NET序列化程序实例:

public class NewtonsoftJsonSerializer : ISerializer
{
    public NewtonsoftJsonSerializer()
        : this(new JsonSerializer
        {
            TypeNameHandling = TypeNameHandling.Auto,
            ObjectCreationHandling = ObjectCreationHandling.Replace,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
            DefaultValueHandling = DefaultValueHandling.Ignore,
            ContractResolver = new KsJsonContractResolver()
        })
    {
        this.serializer.Converters.Add(new BusinessObjectCreationConverter());
    }

    public T Deserialize(Stream stream)
    {
        T result;
        using (var streamReader = new StreamReader(stream, Encoding.UTF8, true, BufferSize, true))
        using (var jsonReader = new JsonTextReader(streamReader))
        {
            result = this.serializer.Deserialize(jsonReader);
        }

        return result;
    }
}

当我反序列化TestBusinessObject时,我可以从调试器看到转换器询问每种类型是否能够创建实例:TestBusinessObject,NestedObject和许多其他类型.但我的转换器只是被要求创建一个新的TestBusinessObject实例,他没有被要求创建我所期望的嵌套NestedObject实例和我非常需要的,因为反序列化ctor中有一些有线逻辑.

我在这里做错了,如何告诉JsonSerializer将转换器用于每个对象,甚至不是根(顶层)对象?

编辑: 当一个BusinessObjectBase实例包含在我不知道的类型的对象中时,认为变得更加复杂.在这种情况下,我也希望调用转换器.

提前谢谢,卡斯滕

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有