Description
Using default configuration, System.Text.Json will serialize values of type objectusing polymorphism. This becomes less consistent once users register a custom converter for object, as witnessed in the following example:
usingSystem;usingSystem.Text.Json;usingSystem.Text.Json.Serialization;varoptions=newJsonSerializerOptions{Converters={newCustomObjectConverter()}};Console.WriteLine(JsonSerializer.Serialize<object>(0,options));// Prints 0, custom converter not honoredConsole.WriteLine(JsonSerializer.Serialize<object[]>(newobject[]{0},options));// Prints [42], custom converter honoredpublicclassCustomObjectConverter:JsonConverter<object>{publicoverridevoidWrite(Utf8JsonWriterwriter,objectvalue,JsonSerializerOptionsoptions)=>writer.WriteNumberValue(42);publicoverrideobjectRead(refUtf8JsonReaderreader,TypetypeToConvert,JsonSerializerOptionsoptions)=>thrownewNotImplementedException();}In short, System.Text.Json has historically been hardcoding polymorphism for root-level object values but not using polymorphism for nested object values. Starting with .NET 7 RC1, this behavior has been changed so that custom converters never use polymorphism.
Version
.NET 7 RC 1
Previous behavior
Using the custom object converter defined above, the code
varoptions=newJsonSerializerOptions{Converters={newCustomObjectConverter()}};JsonSerializer.Serialize<object>(0,options);Will serialize as 0, since the serializer will use polymorphism and ignore the custom converter.
New behavior
Using the custom object converter defined above, the code
varoptions=newJsonSerializerOptions{Converters={newCustomObjectConverter()}};JsonSerializer.Serialize<object>(0,options);Will serialize as 42, since the serializer will always consult the custom converter and not use polymorphism.
Type of breaking change
Reason for change
Inconsistency on serialization contracts for a given type, depending on whether it is being serialized as a root-level value or a nested value.
Recommended action
Users can get back polymorphism for root-level values by invoking one of the untyped serialization methods:
varoptions=newJsonSerializerOptions{Converters={newCustomObjectConverter()}};JsonSerializer.Serialize(0,inputType:typeof(int),options);// serializes as 0Feature area
Core .NET libraries
Affected APIs
No response
Description
Using default configuration, System.Text.Json will serialize values of type
objectusing polymorphism. This becomes less consistent once users register a custom converter forobject, as witnessed in the following example:In short, System.Text.Json has historically been hardcoding polymorphism for root-level
objectvalues but not using polymorphism for nestedobjectvalues. Starting with .NET 7 RC1, this behavior has been changed so that custom converters never use polymorphism.Version
.NET 7 RC 1
Previous behavior
Using the custom object converter defined above, the code
Will serialize as 0, since the serializer will use polymorphism and ignore the custom converter.
New behavior
Using the custom object converter defined above, the code
Will serialize as 42, since the serializer will always consult the custom converter and not use polymorphism.
Type of breaking change
Reason for change
Inconsistency on serialization contracts for a given type, depending on whether it is being serialized as a root-level value or a nested value.
Recommended action
Users can get back polymorphism for root-level values by invoking one of the untyped serialization methods:
Feature area
Core .NET libraries
Affected APIs
No response