物件型別的多型序列化

使用預設組態,object使用多型System.Text.Json 序列化型別的值。 如果您為 object 註冊自訂轉換器,此行為會變得較不一致。 System.Text.Json 具有根層級物件值的硬式編碼多型,但不適用於巢狀物件值。 從 .NET 7 開始,此行為已變更,因此自訂轉換器一律不會使用多型。

先前的行為

請考慮下列自訂物件轉換器:

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();
}

在舊版中,下列程式碼會序列化為 0。 這是因為序列化程式使用多型並忽略自訂轉換器。

var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object>(0, options);

不過,下列程式碼會序列化為 42,因為序列化程式接受自訂轉換器。

var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object[]>(new object[] { 0 }, options);

新的行為

從 .NET 7 開始,使用先前的行為區段中定義的自訂物件轉換器,下列程式碼會序列化為 42。 這是因為序列化程式一律會查閱自訂轉換器,而不會使用多型。

var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object>(0, options);

導入的版本

.NET 7

中斷性變更的類型

這項變更會影響二進位相容性

變更原因

這項變更是因為型別的序列化合約不一致,取決於它是否序列化為根層級值或巢狀值。

如有需要,您可以叫用其中一個不具型別的序列化方法,以取得根層級值的多型:

var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize(0, inputType: typeof(int), options); // Serializes as 0.

受影響的 API