rikkit
rikkit

Reputation: 1137

Serializing type information using a different JsonProperty in Json.Net

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?

Upvotes: 1

Views: 1316

Answers (1)

ZuoLi
ZuoLi

Reputation: 368

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

Upvotes: 2

Related Questions