Neu in .NET 7.0 [23]: Pflichteigenschaften bei der JSON-Deserialisierung

.NET quittiert mit der aktuellen Version das Auslassen von Pflichtattributen bei der JSON-Deserialisierung mit einer Fehlermeldung.

vorlesen Druckansicht

(Bild: Shutterstock)

Lesezeit: 2 Min.
Von
  • Dr. Holger Schwichtenberg

Die JSON-Bibliothek System.Text.Json berĂĽcksichtigt seit .NET 7.0 Pflichtattributen beim Deserialisieren. Wenn ein Pflichtattribut in der JSON-Zeichenkette nicht enthalten ist, gibt es einen Laufzeitfehler. Als Pflichtattribute werden betrachtet:

Der Dotnet-Doktor – Holger Schwichtenberg
Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

  • Field und Properties, die den in C# 11.0 eingefĂĽhrten Modifizierer required haben (siehe Teil 6 der Serie)
  • Field und Properties, die mit [JsonRequired] annotiert sind (neue Annotation in .NET 7.0)
  • Field und Properties, fĂĽr die im Type Info Resolver (siehe Teil 22 dieser Serie) im Objekt JsonPropertyInfo die Eigenschaft IsRequired auf true gesetzt wird.

Videos by heise

Gegeben sei eine Basisklasse Person und eine abgeleitete Klasse Developer, wobei alle Properties mit required versehen sind.

public class Person
{
 public required int ID { get; set; }
 public required string Name { get; set; }
 public override string ToString()
 {
  return $"Person {Name}";
 }
}

public class Developer : Person
{
 public required string? Company { get; set; }
 public override string ToString()
 {
  return $"Developer {Name} entwickelt bei {Company}.";
 }
}

Diese JSON-Deserialierung klappt:

var json1 = """
    {"ID":123,"Company":"MAXIMAGO GmbH",
     "Name":"Holger Schwichtenberg"}
    """;
Developer? D1 = JsonSerializer.Deserialize<Developer>(json1);

Im zweiten Beispiel aber fehlen ID und Company:

var json2 = """
            {"Name":"Holger Schwichtenberg"}
            """;
Developer? d2 = JsonSerializer.Deserialize<Developer>(json2);

Wir kassieren daher diesen Laufzeitfehler:

JSON deserialization for type 'Developer' was missing \
required properties, including the following: Company; ID

Fehlverhalten bei abgeleiteten Klassen

Allerdings gibt es hier eine Anomalie: Wenn wir eine zweite Ableitung von Person mit Klassenname Consultant deklarieren, bei der das Property Company nicht required ist

public class Consultant : Person
{
 public string? Company { get; set; }
 public override string ToString()
 {
  return $"Consultant {Name} arbeitet bei {Company}.";
 }
}

und folgendermaĂźen beim Deserialisieren verwenden

var json3 = """
    {"Company":www.IT-Visions.de,
     "Name":"Holger Schwichtenberg" }
    """;
Consultant? c = JsonSerializer.Deserialize<Consultant>(json3);

dann beschwert sich der JSON-Deserialisierer leider nicht ĂĽber die fehlenden Eigenschaft ID, solange nur required verwendet wird. Dieses unlogische Verhalten steht leider nicht in der Dokumentation.

Wenn man die Annotation [JsonRequired] statt dem Modifizierer required verwendet

public class Person
{
 
 [JsonRequired]
 public int ID { get; set; }
 [JsonRequired]
 public string Name { get; set; }
 public override string ToString()
 {
  return $"Person {Name}";
 }
}

dann klappt es mit der erwarteten Fehlermeldung:

JSON deserialization for type 'Consultant' was missing \ 
required properties, including the following: ID

(rme)