2

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);
    }
}
hwcverwe
  • 5,287
  • 7
  • 35
  • 63
  • 1
    If you change your list to a `Dictionary` you can get the result you want using the `[JsonExtensionData]` attribute. See this [question](http://stackoverflow.com/q/14893614/10263) and [answer](http://stackoverflow.com/a/23786127/10263). – Brian Rogers Sep 03 '14 at 18:58

1 Answers1

1

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.

Ilija Dimov
  • 5,221
  • 7
  • 35
  • 42
  • This works but unfortunately it has a big drawback.. All developers needs to be aware that one object in the current structure requires its own converter. All other objects works with the [JsonProperty] and the [JsonIgnore] attributes. But I don't see any other ways of doing it at the moment. Thanks! – hwcverwe Sep 04 '14 at 09:33