Search code examples
c#serializationsystem.text.jsonjsonconvertjsonconverter

Why is JsonConverter attribute not inherited from interface?


In have the following code:

interface ITyped<TypeEnum> where TypeEnum : Enum, struct
{
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public TypeEnum Type { get; }
}

class Foo : ITyped<FooType>
{
    public Foo(FooType type) { Type = type; }

    public FooType Type { get; init; }
}

enum FooType { type1, type2 }

If I serialize a Foo instance with System.Text.Json.JsonSerializer, I get an int for the Type property - although I have specified a JsonStringEnumConverter for the Type property in the interface.

var foo = new Foo(FooType.type1);
var json = JsonSerializer.Serialize(foo);
    // contains {"Type":0} but I want {"Type":"type1"}

It does work if I attach the [JsonConverter(typeof(JsonStringEnumConverter))] to the Type property of Foo instead.

But why does it not work if it is attached to the Type property of the interface?

The docs say that JsonConverterAttribute can be put on System.AttributeTargets.Property, and since it derives from Attribute, it is also Inherited=true.


Solution

  • The key part is that classes implement interfaces, they don't inherit them.

    I see the following options:

    • Use a base class
    • Use JsonStringEnumConverter "globally" instead of decorating individual members:
      var options = new JsonSerializerOptions();
      options.Converters.Add(new JsonStringEnumConverter());
      JsonSerializer.Serialize(foo);