Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ake a look at this other SO: How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?.
- I used this as the basis for my own solution to the same problem.
- Starting off with the JsonCreationConverter<T> referenced in that SO (slightly modified to fix issues with serialization of types in responses):
- public abstract class JsonCreationConverter<T> : JsonConverter
- {
- /// <summary>
- /// this is very important, otherwise serialization breaks!
- /// </summary>
- public override bool CanWrite
- {
- get
- {
- return false;
- }
- }
- /// <summary>
- /// Create an instance of objectType, based properties in the JSON object
- /// </summary>
- /// <param name="objectType">type of object expected</param>
- /// <param name="jObject">contents of JSON object that will be
- /// deserialized</param>
- /// <returns></returns>
- protected abstract T Create(Type objectType, JObject jObject);
- public override bool CanConvert(Type objectType)
- {
- return typeof(T).IsAssignableFrom(objectType);
- }
- public override object ReadJson(JsonReader reader, Type objectType,
- object existingValue, JsonSerializer serializer)
- {
- if (reader.TokenType == JsonToken.Null)
- return null;
- // Load JObject from stream
- JObject jObject = JObject.Load(reader);
- // Create target object based on JObject
- T target = Create(objectType, jObject);
- // Populate the object properties
- serializer.Populate(jObject.CreateReader(), target);
- return target;
- }
- public override void WriteJson(JsonWriter writer, object value,
- JsonSerializer serializer)
- {
- throw new NotImplementedException();
- }
- }
- And now you can annotate your type with the JsonConverterAttribute, pointing Json.Net to a custom converter:
- [JsonConverter(typeof(MyCustomConverter))]
- public abstract class BaseClass{
- private class MyCustomConverter : JsonCreationConverter<BaseClass>
- {
- protected override BaseClass Create(Type objectType,
- Newtonsoft.Json.Linq.JObject jObject)
- {
- //TODO: read the raw JSON object through jObject to identify the type
- //e.g. here I'm reading a 'typename' property:
- if("DerivedType".Equals(jObject.Value<string>("typename")))
- {
- return new DerivedClass();
- }
- return new DefaultClass();
- //now the base class' code will populate the returned object.
- }
- }
- }
- public class DerivedClass : BaseClass {
- public string DerivedProperty { get; set; }
- }
- public class DefaultClass : BaseClass {
- public string DefaultProperty { get; set; }
- }
- Now you can use the base type as a parameter:
- public Result Post(BaseClass arg) {
- }
- And if we were to post:
- { typename: 'DerivedType', DerivedProperty: 'hello' }
- Then arg would be an instance of the DerivedClass, but if we posted:
- { DefaultProperty: 'world' }
- Then you'd get an instance of the DefaultClass.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement