3

I have an abstract class named Extension which has several derived classes such as DerivedExtensionA, DerivedExtensionB, etc.

Now I have a list defined as List<Extension> which contains the derived classes instances.

Now if I serialize the above list, it only serializes the base class properties that are in Extension since the list has the base class Extension type. If I define the list as List<DerivedExtensionA> and then put only instances of DerivedExtensionA in it, then they are serialized fine. But my code is generic which is supposed to accept all types of Extensions, so this isn't a workable solution for me.

So question is ..

How do I keep the list defined as List<Extension> and still be able to fully serialize the contained derived class instances that contain ALL their properties ?

Here is a fiddle showing this behavior: https://dotnetfiddle.net/22mbwb

EDIT: Corrected the fiddle URL

Ahmad
  • 12,886
  • 30
  • 93
  • 146
  • I just corrected the fiddle URL. – Ahmad Mar 30 '22 at 23:07
  • This is [as designed and documented](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-polymorphism). You can either 1) Add a `JsonConverter` that serializes the derived classes explicitly as shown in [Serialize objects implementing interface with System.Text.Json](https://stackoverflow.com/a/66498917/3744182), or 2) serialize your `List` via an `IEnumerable` surrogate property as shown in [System.Text.Json serialize derived class property](https://stackoverflow.com/a/65664460). – dbc Mar 30 '22 at 23:32
  • If you also need to deserialize you will need to add a type discriminator property. See [Is polymorphic deserialization possible in System.Text.Json?](https://stackoverflow.com/q/58074304/3744182) for many converters that do this. – dbc Mar 30 '22 at 23:33
  • Do those questions answer yours also, or do you need more specific help? [Why does System.Text Json Serialiser not serialise this generic property but Json.NET does?](https://stackoverflow.com/q/62033264/3744182) also addresses this problem. – dbc Mar 30 '22 at 23:33

2 Answers2

2

From How to serialize properties of derived classes with System.Text.Json

Serialization of a polymorphic type hierarchy is not supported.

In your fiddle you can use an array of objects:

string allExtensionsSerialized =
   JsonSerializer.Serialize((object[])allExtensions.ToArray());

This is the hack I used recently:

public record MyType(
   // This nonsense is here because System.Text.Json does not support normal polymorphic serialisation
   [property: JsonIgnore] List<X> Messages))
{
   // This nonsense is here because System.Text.Json does not support normal polymorphic serialisation
   [JsonPropertyName("Messages")]
   public object[] MessagesTrick => Messages.ToArray();

For deserialisation, I decided used JsonDocument.Parse inside a dedicated FromJson(string json) method. This works OK, for me, in this specific case.

tymtam
  • 31,798
  • 8
  • 86
  • 126
0

Actually I ended up changing the definition of the list from List<Extension> to List<object>, and the behavior was corrected. This might not be a workable solution for everyone reading this, but it's fine for me so that's why I'm adding my own answer.

Ahmad
  • 12,886
  • 30
  • 93
  • 146