Polymorphic serialization for object types
Using default configuration, System.Text.Json serializes values of type object
using polymorphism. This behavior becomes less consistent if you register a custom converter for object
. System.Text.Json
has historically hardcoded polymorphism for root-level object values but not for nested object values. Starting with .NET 7, this behavior has changed so that custom converters never use polymorphism.
Consider the following custom object converter:
public class CustomObjectConverter : JsonConverter<object>
{
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
=> writer.WriteNumberValue(42);
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> throw new NotImplementedException();
}
In previous versions, the following code serialized as 0. That's because the serializer used polymorphism and ignored the custom converter.
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object>(0, options);
However, the following code serialized as 42 because the serializer honored the custom converter.
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object[]>(new object[] { 0 }, options);
Starting in .NET 7, using the custom object converter defined in the Previous behavior section, the following code serializes as 42. That's because the serializer will always consult the custom converter and not use polymorphism.
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object>(0, options);
.NET 7
This change can affect binary compatibility.
This change was made due to inconsistent serialization contracts for a type, depending on whether it was being serialized as a root-level value or a nested value.
If desired, you can get back polymorphism for root-level values by invoking one of the untyped serialization methods:
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize(0, inputType: typeof(int), options); // Serializes as 0.
- System.Text.Json.JsonSerializer.Serialize<TValue>(TValue, JsonSerializerOptions)
- System.Text.Json.JsonSerializer.Serialize<TValue>(Stream, TValue, JsonSerializerOptions)
- System.Text.Json.JsonSerializer.Serialize<TValue>(Utf8JsonWriter, TValue, JsonSerializerOptions)
- System.Text.Json.JsonSerializer.SerializeAsync<TValue>(Stream, TValue, JsonSerializerOptions, CancellationToken)
.NET feedback
.NET er et åben kildekode projekt. Vælg et link for at give feedback: