2

I've got a simple CLI app that gets some different data depending on args and then JSON serializes it using System.Text.Json.

The problem I'm running into is when serializing a derived class (ie. List<DerivedImage> in this case) with a custom converter for the base class (ie. ImageConverter).

public static int Main(string[] args)
{
  object data = "images ls" switch
  {
    "images ls" => new List<DerivedImage>() { new DerivedImage() },
    // ... etc ...
  };

  var options = new JsonSerializerOptions()
  {
    Converters = { new ImageConverter() }
  };

  var stringified = JsonSerializer.Serialize(data, options);
  // ^ THIS ERRORS!
  // Exception message:
  // System.InvalidCastException: 'Unable to cast object of type 'ImageConverter'
  // to type 'JsonConverter[DerivedImage]'

  return 1;
}

public class ImageConverter : JsonConverter<Image>
{
  public override bool CanConvert(Type typeToConvert)
  {
    return typeof(Image).IsAssignableFrom(typeToConvert);
  }

  public override Image Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  {
    throw new NotImplementedException();
  }

  public override void Write(Utf8JsonWriter writer, Image value, JsonSerializerOptions options)
  {
    // It never gets here.
  }
}

public abstract class Image { }

public class DerivedImage : Image { }

With the snippet above, how can I get the serializer to use the ImageConverter when passed data?

L. Berger
  • 266
  • 2
  • 15
  • 1
    While `Image` and `DerivedImage` are related by inheritance, `JsonConverter` and `JsonConverter` are not. So, since `ImageConverter` is-a `JsonConverter`, it still cannot be cast to `JsonConverter`. – Fildor Aug 03 '23 at 18:44
  • @dbc Got it, example is runnable now @Fildor-standswithMods Is there some other way to make the `ImageConverter` usable by its derived classes? I'd imagine it'd work if I create a converter for each derived class (ie. `JsonConverter`), but that'd get repetitive – L. Berger Aug 03 '23 at 18:49
  • Your newest code runs successfully without an `InvalidCastException` when I add some logic into `ImageConverter.Write()`, see https://dotnetfiddle.net/eziNWz. We still need to see a [mcve]. – dbc Aug 03 '23 at 18:53
  • 1
    By the way, .NET 7 has built-in support for polymorphism, see [this answer](https://stackoverflow.com/a/74352597/3744182) to [Is polymorphic deserialization possible in System.Text.Json?](https://stackoverflow.com/q/58074304/3744182). If the only purpose of your converter is to support polymorphism, you could consider switching to the builtin mechanism. – dbc Aug 03 '23 at 18:57
  • Wow, you're completely right. I was actually running this with `.net6` originally as the target framework, but it works completely fine with `.net7` as the target instead. Also, thanks for the advice regarding built-in polymorphic support in .NET 7. I reckon I'll still stick with a custom converter though - I have a lot of custom logic for how the JSON should be formatted in the real use case. – L. Berger Aug 03 '23 at 19:10

1 Answers1

0

Resolved by upgrading TargetFramework in the project config from .net6 to .net7.

L. Berger
  • 266
  • 2
  • 15