Freigeben über


Polymorphe Serialisierung für Objekttypen

Mit der Standardkonfiguration serialisiert System.Text.Json Werte des Typs objectmithilfe der Polymorphie. Dieses Verhalten wird weniger konsistent, wenn Sie einen benutzerdefinierten Konverter für object registrieren. System.Text.Json hat in der Vergangenheit Polymorphie für Objektwerte auf Stammebene, aber nicht für verschachtelte Objektwerte hartcodiert. Ab .NET 7 hat sich dieses Verhalten dahingehend geändert, dass benutzerdefinierte Konverter niemals Polymorphie verwenden.

Vorheriges Verhalten

Betrachten Sie den folgenden benutzerdefinierten Objektkonverter:

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 früheren Versionen wurde der folgende Code als 0 serialisiert. Das liegt daran, dass der Serialisierer Polymorphie verwendet und den benutzerdefinierten Konverter ignoriert hat.

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

Der folgende Code wurde jedoch als 42 serialisiert, da der Serialisierer den benutzerdefinierten Konverter berücksichtigt hat.

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

Neues Verhalten

Ab .NET 7 wird der folgende Code unter Verwendung des im Abschnitt Vorheriges Verhalten definierten benutzerdefinierten Objektkonverters als 42 serialisiert. Das liegt daran, dass der Serialisierer immer den benutzerdefinierten Konverter verwendet und keine Polymorphie einsetzt.

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

Eingeführt in Version

.NET 7

Typ des Breaking Changes

Diese Änderung kann sich auf die binäre Kompatibilität auswirken.

Grund für die Änderung

Diese Änderung wurde aufgrund inkonsistenter Serialisierungsverträge für einen Typ vorgenommen, je nachdem, ob er als Wert auf Stammebene oder als geschachtelter Wert serialisiert wurde.

Bei Bedarf können Sie die Polymorphie für Werte auf Stammebene zurückgeben, indem Sie eine der nicht typisierten Serialisierungsmethoden aufrufen:

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

Betroffene APIs