Advertisement
Guest User

Untitled

a guest
Nov 20th, 2019
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.05 KB | None | 0 0
  1. ake a look at this other SO: How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?.
  2.  
  3. I used this as the basis for my own solution to the same problem.
  4.  
  5. Starting off with the JsonCreationConverter<T> referenced in that SO (slightly modified to fix issues with serialization of types in responses):
  6.  
  7. public abstract class JsonCreationConverter<T> : JsonConverter
  8. {
  9. /// <summary>
  10. /// this is very important, otherwise serialization breaks!
  11. /// </summary>
  12. public override bool CanWrite
  13. {
  14. get
  15. {
  16. return false;
  17. }
  18. }
  19. /// <summary>
  20. /// Create an instance of objectType, based properties in the JSON object
  21. /// </summary>
  22. /// <param name="objectType">type of object expected</param>
  23. /// <param name="jObject">contents of JSON object that will be
  24. /// deserialized</param>
  25. /// <returns></returns>
  26. protected abstract T Create(Type objectType, JObject jObject);
  27.  
  28. public override bool CanConvert(Type objectType)
  29. {
  30. return typeof(T).IsAssignableFrom(objectType);
  31. }
  32.  
  33. public override object ReadJson(JsonReader reader, Type objectType,
  34. object existingValue, JsonSerializer serializer)
  35. {
  36. if (reader.TokenType == JsonToken.Null)
  37. return null;
  38. // Load JObject from stream
  39. JObject jObject = JObject.Load(reader);
  40.  
  41. // Create target object based on JObject
  42. T target = Create(objectType, jObject);
  43.  
  44. // Populate the object properties
  45. serializer.Populate(jObject.CreateReader(), target);
  46.  
  47. return target;
  48. }
  49.  
  50. public override void WriteJson(JsonWriter writer, object value,
  51. JsonSerializer serializer)
  52. {
  53. throw new NotImplementedException();
  54. }
  55. }
  56. And now you can annotate your type with the JsonConverterAttribute, pointing Json.Net to a custom converter:
  57.  
  58. [JsonConverter(typeof(MyCustomConverter))]
  59. public abstract class BaseClass{
  60. private class MyCustomConverter : JsonCreationConverter<BaseClass>
  61. {
  62. protected override BaseClass Create(Type objectType,
  63. Newtonsoft.Json.Linq.JObject jObject)
  64. {
  65. //TODO: read the raw JSON object through jObject to identify the type
  66. //e.g. here I'm reading a 'typename' property:
  67.  
  68. if("DerivedType".Equals(jObject.Value<string>("typename")))
  69. {
  70. return new DerivedClass();
  71. }
  72. return new DefaultClass();
  73.  
  74. //now the base class' code will populate the returned object.
  75. }
  76. }
  77. }
  78.  
  79. public class DerivedClass : BaseClass {
  80. public string DerivedProperty { get; set; }
  81. }
  82.  
  83. public class DefaultClass : BaseClass {
  84. public string DefaultProperty { get; set; }
  85. }
  86. Now you can use the base type as a parameter:
  87.  
  88. public Result Post(BaseClass arg) {
  89.  
  90. }
  91. And if we were to post:
  92.  
  93. { typename: 'DerivedType', DerivedProperty: 'hello' }
  94. Then arg would be an instance of the DerivedClass, but if we posted:
  95.  
  96. { DefaultProperty: 'world' }
  97. Then you'd get an instance of the DefaultClass.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement