You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
System.Text.Json Polymorphism Type Discriminator Does Not Support Subtypes Class Polymorphism #101286
I tried running the reproduction and it seems to be working as expected, i.e. the discriminator "post_type" : "meta_event" is being mapped to an instance of type MetaEvent, when deserializing as EventBase. I'm not entirely sure what your expected behavior is in this case, but I have two remarks based on what I'm seeing:
The JsonDerivedType/JsonPolymorphic annotations on MetaEvent are not inherited by EventBase. These set up independent sets of configurations depending on whether you are calling Deserialize<EventBase> or Deserialize<MetaEvent>.
I see you are creating properties whose names match the type discriminator property name. I should note that this isn't supported, the run-time value of these properties (as set via the overrides) does not have any influence on what a payload deserializes to. This is solely guided by the attribute annotations.
How should I deserialize into the MetaLifecycleEvent class?
EventBase is the base class for all events, MetaEvent is a broad category of events, with MetaLifecycleEvent belonging to the MetaEvent class, which in turn belongs to EventBase.
I think that when serializing/deserializing, if a subclass specified, it should check whether the subclass has the JsonPolymorphic or JsonDerivedType attributes. If these attributes exist, the process should continue.
You would need to add a JsonDerivedType annotation for MetaLifecycleEvent in EventBase. If you're feeling fancy (and you're not working with Native AOT or trimmed applications) you can write a contract customizer that looks up the type hierarchy using reflection and automatically appends JsonDerivedAttribute annotations to the base.
I think that when serializing/deserializing, if a subclass specified, it should check whether the subclass has the JsonPolymorphic or JsonDerivedType attributes. If these attributes exist, the process should continue.
That might work when using reflection-based serialization, but it might not be possible using the source generator which needs to know the entire hierarchy at compile time. Therefore, it is not supported (though there are ways to achieve this via contract customization).
Activity
eiriktsarpalis commentedon Apr 19, 2024
I tried running the reproduction and it seems to be working as expected, i.e. the discriminator
"post_type" : "meta_event"is being mapped to an instance of typeMetaEvent, when deserializing asEventBase. I'm not entirely sure what your expected behavior is in this case, but I have two remarks based on what I'm seeing:JsonDerivedType/JsonPolymorphicannotations onMetaEventare not inherited byEventBase. These set up independent sets of configurations depending on whether you are callingDeserialize<EventBase>orDeserialize<MetaEvent>.Hope this helps.
bunnyi116 commentedon Apr 19, 2024
How should I deserialize into the MetaLifecycleEvent class?
EventBase is the base class for all events, MetaEvent is a broad category of events, with MetaLifecycleEvent belonging to the MetaEvent class, which in turn belongs to EventBase.
bunnyi116 commentedon Apr 19, 2024
I think that when serializing/deserializing, if a subclass specified, it should check whether the subclass has the
JsonPolymorphicorJsonDerivedTypeattributes. If these attributes exist, the process should continue.eiriktsarpalis commentedon Apr 19, 2024
You would need to add a
JsonDerivedTypeannotation forMetaLifecycleEventinEventBase. If you're feeling fancy (and you're not working with Native AOT or trimmed applications) you can write a contract customizer that looks up the type hierarchy using reflection and automatically appends JsonDerivedAttribute annotations to the base.That might work when using reflection-based serialization, but it might not be possible using the source generator which needs to know the entire hierarchy at compile time. Therefore, it is not supported (though there are ways to achieve this via contract customization).
bunnyi116 commentedon Apr 19, 2024
I don't need AOT.
Could you help me write a simple example using custom contracts for my sample data? I'm not very familiar with it.
Also, I hope STJ can find a way to support AOT in the future.