Bagikan melalui


Serialisasi polimorfik untuk jenis objek

Menggunakan konfigurasi default, System.Text.Json menserialisasikan nilai jenis objectmenggunakan polimorfisme. Perilaku ini menjadi kurang konsisten jika Anda mendaftarkan pengonversi kustom untuk object. System.Text.Json memiliki polimorfisme yang dikodekan secara historis untuk nilai objek tingkat akar tetapi tidak untuk nilai objek berlapis. Dimulai dengan .NET 7, perilaku ini telah berubah sehingga pengonversi kustom tidak pernah menggunakan polimorfisme.

Perilaku sebelumnya

Pertimbangkan pengonversi objek kustom berikut:

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

Di versi sebelumnya, kode berikut diserialisasikan sebagai 0. Itu karena serializer menggunakan polimorfisme dan mengabaikan pengonversi kustom.

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

Namun, kode berikut diserialisasikan sebagai 42 karena serializer menghormati pengonversi kustom.

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

Perilaku yang baru

Mulai dari .NET 7, menggunakan pengonversi objek kustom yang ditentukan di bagian Perilaku sebelumnya, kode berikut diserialisasikan sebagai 42. Itu karena serializer akan selalu berkonsultasi dengan pengonversi kustom dan tidak menggunakan polimorfisme.

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

Versi yang diperkenalkan

.NET 7

Jenis perubahan yang melanggar

Perubahan ini dapat memengaruhi kompatibilitas biner.

Alasan untuk berubah

Perubahan ini dilakukan karena kontrak serialisasi yang tidak konsisten untuk jenis, tergantung pada apakah itu diserialisasikan sebagai nilai tingkat akar atau nilai berlapis.

Jika diinginkan, Anda bisa mendapatkan kembali polimorfisme untuk nilai tingkat akar dengan memanggil salah satu metode serialisasi yang tidak diketik:

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

API yang Terpengaruh