简体   繁体   中英

JSON.NET serializing list as properties of parent object

I have an object which contains a list of additional information.

public class ParentObject 
{
    public string Prop1{ get; set; }
    public string Prop2{ get; set; }
    public IList<BaseInformation> AdditionalInformation{get;set;}
}

public abstract class AbstractInformation {}

public class ConcreteInformation1 : AbstractInformation
{
    public string Concrete1Extra1{ get; set; }
    public string Concrete1Extra2{ get; set; }
} 
public class ConcreteInformation2 : AbstractInformation
{
    public string Concrete2Extra1{ get; set; }
}

I want to have an json object like this

{
    "Prop1": "MyValue1", //From ParentObject
    "Prop2": "MyValue2", //From ParentObject
    "Concrete1Extra1" : "Extra1" // From ConcreteInformation1
    "Concrete1Extra2" : "Extra2" // From ConcreteInformation1
    "Concrete2Extra1" : "Extra3" // From ConcreteInformation2
}

I know my goal looks very error prone (Having two ConcreteInformation1 objects in the list will cause duplicate property names) but I simpified my question and example in order to focus only on finding a solution for combining the list as properties into the parent object.

I have tried to write my own JsonConverter but that's giving an error on o.AddBeforeSelf() because the JObject.Parent is null.

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    JToken t = JToken.FromObject(value);

    if (t.Type != JTokenType.Object)
    {
        t.WriteTo(writer);
    }
    else
    {
        JObject o = (JObject)t;

        o.AddBeforeSelf(new JProperty("PropertyOnParent", "Just a test"));

        o.WriteTo(writer);
    }
}

Try change the WriteJson method to look like this:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    if (value == null || !(value is ParentObject))
        return;

    var pObject = (ParentObject) value;

    writer.WriteStartObject();

    writer.WritePropertyName("Prop1");
    writer.WriteValue(pObject.Prop1);
    writer.WritePropertyName("Prop2");
    writer.WriteValue(pObject.Prop2);

    foreach (var info in pObject.AdditionalInformation)
    {
        JObject jObj = JObject.FromObject(info);
        foreach (var property in jObj.Properties())
        {
            writer.WritePropertyName(property.Name);
            writer.WriteValue(property.Value);
        }
    }

    writer.WriteEndObject();
}

But as you said, be careful when having more than one object from same type in the collection. It will generate multiple properties with same property names in the json string and you'll have problems during deserialization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM