1

I have created several classes that map to Schema.org objects;

public class Thing {
    public virtual string FullSchemaType { get { return "[schema.org]Thing"; } }
}

public class CreativeWork : Thing {
    public override string FullSchemaType {get {return string.Join(":", base.FullSchemaType, "CreativeWork"); } }

    [JsonProperty("author")]
    public string Author { get;set; }
    // etc
}

public class MediaObject : CreativeWork {
    public override string FullSchemaType {get {return string.Join(":", base.FullSchemaType, "MediaObject"); } }

    [JsonProperty("duration")]
    public float? Duration { get;set; }
}

I have a factory class that creates e.g. a MediaObject, sets its properties. The FullSchemaType property is a Schema.org compliant way of noting its type. I am putting these objects into a database, serialising them using Json.NET 6.0.3.

I want to deserialize them into the correct C# objects. The standard Json.Net way to do this is to use TypeNameHandling - but that inserts a $type property into the serialised Json, which isn't ideal as we have several different applications interfacing with this database.

Is there a way to tell Json.NET to look at my FullSchemaType property for type binding information?

rikkit
  • 1,127
  • 3
  • 18
  • 35

1 Answers1

2

You can use JsonSerializerSettings to customise parameters of serialization: setting TypeNameHandling = TypeNameHandling.None allows you not to include $type information in serialized Json, and if you have any further problems with, say, customised converters you can use JsonSerializerSettings.IList<JsonConverter> settings to specify ones.

More detailed info is here: JsonSerializerSettings

and here: Newtonsoft.Json.TypeNameHandling

And here is a good example of JsonCreationConverter, you can overrride method ReadJson in your own converter, based on JsonConverter like this:

public override object ReadJson(JsonReader reader, 
                                Type objectType, 
                                 object existingValue, 
                                 JsonSerializer serializer)
{
    // Load JObject from stream
    JObject jObject = JObject.Load(reader);

    if (jObject[FullSchemaType] == {your_media_object_type_name})
        MediaObject target = Create(objectType, jObject);
    else if (jObject[FullSchemaType] == {your_creative_work_type_name})
        CreativeWork target = Create(objectType, jObject);
    else
        Thing target = Create(objectType, jObject);

    // Populate the object properties
    serializer.Populate(jObject.CreateReader(), target);

    return target;
}
Community
  • 1
  • 1
ZuoLi
  • 383
  • 2
  • 14
  • I need the type information - I just don't want it to be called $type. FullSchemaType is already being serialized so I want to be able to use that property instead. – rikkit Oct 31 '14 at 14:04
  • So, why not to implement your own JsonCreationConverter class from this answer? http://stackoverflow.com/questions/8030538/how-to-implement-custom-jsonconverter-in-json-net-to-deserialize-a-list-of-base?rq=1 – ZuoLi Oct 31 '14 at 14:08