JSON.NET CustomCreationConverter with nested objects

穿精又带淫゛_ 提交于 2019-12-10 15:08:53

问题


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

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)
    {
    }
}

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;
    }
}

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

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;
    }
}

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.

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?

EDIT: 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.

Thanks in advance, Carsten


回答1:


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; }
}


来源:https://stackoverflow.com/questions/20406717/json-net-customcreationconverter-with-nested-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!