System.Text.Json polymorphism strange behaviour? #101454
-
I ran into a, what I find, strange behaviour using System.Text.Json to serialize a class hierarchy. I'd like to understand what's going on, so would be grateful if anyone could explain it to me. Running the following code (full repro) fails on the second assert, but not the first. In the second case the object gets serialized without type discriminator, and hence gets deserialized to the base object. However, if I add a JsonDerivedType attribute to the subclass the second assert passes as well. So why are the results different to begin with? Why does the JsonDerivedType make a difference in the second case, and should it be needed? Am I missing something basic here? Thanks in advance! Running .Net 8.
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The reason is the different type of the serialized variables
In your second case, var s2 = JsonSerializer.Serialize(t2); infers var s2 = JsonSerializer.Serialize<TransactionType>(t2); (which explicitly serializes t2 as the base type Or use var s2 = JsonSerializer.Serialize<object>(t2); Alternatively, you could also change var t2 = TransactionType.Purchase.Inventory; to either TransactionType t2 = TransactionType.Purchase.Inventory; or object t2 = TransactionType.Purchase.Inventory; and the second assert should also pass. And the other way around, you could make the first assert fail by replacing var s1 = JsonSerializer.Serialize(t1); with var s1 = JsonSerializer.Serialize((InventoryPurchase) t1); Note that serializing a variable of type public class Base { }
[JsonDerivedType(derivedType: typeof(InventoryPurchase), typeDiscriminator: nameof(InventoryPurchase))]
public class TransactionType : Base
{
... This makes var s2 = JsonSerializer.Serialize<Base>(t2); will (unlike when using
In my opinion, this seems to be STJ checking for the respective attributes on the type of the value passed to the (generic) |
Beta Was this translation helpful? Give feedback.
The reason is the different type of the serialized variables
t1
(object) andt2
(InventoryPurchase). Per the polymorphic serialization guide at https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism:In your second case,
infers
Inventory…