Reputation: 1137
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
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