CustomCreationConverter

CustomCreationConverter

本文介绍了带有嵌套对象的JSON.NET CustomCreationConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

that is my very first question I ask on this site, so forgive me if I missed something.

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

I have some problems deserializing an complex object graph using JSON.NET. My class hierarchy is (simplified) as follows:

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一起),如示例中所示.为了创建实例,我编写了一个自定义创建转换器,如下所示:

The classes don't have a default ctor, but a dedicated custom deserialization ctor (beside other public ctor with parameters) as shown in the example. To create an instance I have written an custom creation converter like this:

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

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

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

The CreateUsingDesrializationConstructor() extension method looks for the special deserialization ctor and creates an instance using the ctor.

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

I added to the converter to my JSON.NET serializer instance:

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<T>(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<T>(jsonReader);
        }

        return result;
    }
}

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

When I deserialize an TestBusinessObject I can see from the debugger that the converter is ask for every type whether he is able to create an instance: TestBusinessObject, NestedObject and many other types. But my converter is only requested to create a new TestBusinessObject instance, he is NOT requested to create the nested NestedObject instance what I have expected and what I badly need, since there is some wired logic in the deserialization ctor.

我在这里做错什么,如何告诉JsonSerializer对每个对象甚至对根(顶层)对象都使用转换器?

What I'm doing wrong here, how to tell the JsonSerializer to use the converter for every object not even for the root (top level) object?

当BusinessObjectBase实例包含在我不知道类型的对象中时,思考会变得更加复杂.在这种情况下,我也希望调用该转换器.

Thinks become more even more complicated when a BusinessObjectBase instance is contained in an object that type I don't know. In this case I also want that the converter is called.

预先感谢,卡斯滕

推荐答案

尝试为要序列化或反序列化的类赋予[DataContract]属性,并确保这些类中的任何数据也具有这些属性.例如

Try to give [DataContract] attributes to your classes that you want to serialize or deserialize and also make sure whatever data you have in these classes they are also having this attribute. for e.g.

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

    public NestedObject InnerObject { get; set; }
}

这篇关于带有嵌套对象的JSON.NET CustomCreationConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 10:36