Neu in .NET 7.0 [22]: Angepasste JSON-Serialisierung mit Type Info Resolvers
Das Anpassen der Serialisierung und Deserialisierung von JSON-Inhalten ist nĂĽtzlich, wenn die zu serialisierende Klasse nicht im Sourcecode verfĂĽgbar ist.
(Bild: Blackboard/Shutterstock.com)
- Dr. Holger Schwichtenberg
Der neuere, in .NET Core 3.0 eingeführte JSON-Serializer System.Text.Json bietet seit Version 7.0 eine Anpassbarkeit der Serialisierung über sogenannte Type Info Resolver. So kann man die Serialisierung und Deserialisierung anpassen, ohne die zu betreffende .NET-Klasse verändern zu müssen. Das ist hilfreich, falls die zu (de-)serialisierende .NET-Klasse nicht im Quellcode vorliegt.
System.Text.Json ist zusammen mit .NET 7.0 als NuGet-Paket erschienen, läuft aber auch unter .NET Standard 2.0 und damit auch auf .NET Core 2.x/3.x sowie .NET 5.0/.NET 6.0 auf dem klassischen .NET Framework ab Version 4.6.2.
Videos by heise
Der Programmcode im Listing sorgt dafĂĽr, dass
- bei Serialisierung- und Deserialisierung der Klasse
Punktdie PropertyMemoignoriert wird und - die Koordinaten X und Y (beide als Zahl vom Typ "int" deklariert) auch aus Zeichenketten wie "123" und "456" deserialisierbar sind.
Die Eigenschaft TypeInfoResolver in den JsonSerializerOptions ist vom Typ IJsonTypeInfoResolver.
/// <summary>
/// Zu serialiserende Datenklasse
/// </summary>
public class Point
{
public int X { get; set; }
public int Y { get; set; }
public string Memo { get; set; } = "?";
}
public class FCL_JSON
{
/// <summary>
/// Type Info Resolver = Einflussnahme auf die
/// (De-)Serialisierung, ohne Datenklasse verändern zu müssen
/// Verwendet Datenklasse Point
/// </summary>
public static void JSON_TypeInfoResolver()
{
CUI.H2(nameof(JSON_TypeInfoResolver));
JsonSerializerOptions options = new()
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
{
Modifiers =
{
(JsonTypeInfo jsonTypeInfo) =>
{
// Ignoriere alle Properties, die mit "Memo" beginnen
var memoProp =
jsonTypeInfo.Properties.FirstOrDefault(p=>p.Name.StartsWith("Memo"));
if (memoProp != null)
{
jsonTypeInfo.Properties.Remove(memoProp);
}
// Erlaube Zahlen aus Zeichenketten zu deserialisieren
if (jsonTypeInfo.Type == typeof(int))
{
jsonTypeInfo.NumberHandling =
JsonNumberHandling.AllowReadingFromString;
}
}
}
}
};
// Serialisierung
var p1 = new Point() { X = 1, Y = 2, Memo = "Testpunkt" };
var json1 = JsonSerializer.Serialize(p1, options);
Console.WriteLine(json1); // Ausgabe: {"X":1,"Y":2}
// Deserialisierung
string json2 = """
{
"X":"123","Y":"456","Memo":"Testposition"
}
""";
Console.WriteLine("Angepasste Deserialisierung von\n" + json2);
Point? p2 = JsonSerializer.Deserialize<Point>(json2, options);
if (p2 is not null) Console.WriteLine($"({p2.X},{p2.Y},{p2.Memo})");
// Ausgabe: (123,456,?)
}
Weitere Möglichkeiten, die Type Info Resolver einzusetzen, behandelt ein Blogbeitrag.
(rme)