Last active
October 27, 2021 20:53
-
-
Save nickwesselman/b4958828a8a8e5e3656ce8dbc8ebcdc0 to your computer and use it in GitHub Desktop.
.NET 6 System.Text.Json.Nodes and System.Text.Json source generation, with top-level statements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
using System.Text.Json; | |
using System.Text.Json.Nodes; | |
using System.Text.Json.Serialization; | |
/* | |
Testing out .NET 6 JSON DOM for "late binding" of models to a document with unknown structure. | |
Also added source generation for JSON deserialization, both for the base model and the "late bound" model. | |
{ | |
"name": "Nick", | |
"pets": [ | |
{ | |
"name": "Moon", | |
"type": "Cat", | |
"attributes": { | |
"ownsTheHouse": true | |
} | |
}, | |
{ | |
"name": "Melody", | |
"type": "Dog", | |
"attributes": { | |
"isAGoodDog": true | |
} | |
} | |
] | |
} | |
*/ | |
var jsonString = "{\r\n \"name\": \"Nick\",\r\n \"pets\": [\r\n {\r\n \"name\": \"Moon\",\r\n \"type\": \"Cat\",\r\n \"attributes\": {\r\n \"ownsTheHouse\": true\r\n }\r\n },\r\n {\r\n \"name\": \"Melody\",\r\n \"type\": \"Dog\",\r\n \"attributes\": {\r\n \"isAGoodDog\": true\r\n }\r\n }\r\n ]\r\n}"; | |
var jsonOptions = new JsonSerializerOptions | |
{ | |
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | |
}; | |
jsonOptions.AddContext<PersonJsonContext>(); // represents our base model | |
var lateBoundOptions = new JsonSerializerOptions | |
{ | |
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | |
}; | |
lateBoundOptions.AddContext<MyJsonContext>(); // SDK consumers could provide as perf benefit | |
var stopwatch = new Stopwatch(); | |
stopwatch.Start(); | |
var person = JsonSerializer.Deserialize<Person>(jsonString, jsonOptions); | |
Console.WriteLine($"hello {person?.Name}"); | |
foreach (var pet in person.Pets) | |
{ | |
Console.WriteLine($"hello {pet.Name} you {pet.Type}!"); | |
switch (pet.Type.ToLowerInvariant()) | |
{ | |
case "dog": | |
Console.WriteLine($"Are you a good dog? {pet.Attributes["isAGoodDog"]}"); | |
var dog = pet.Attributes.Deserialize<Dog>(lateBoundOptions); | |
if (dog.IsAGoodDog) | |
{ | |
Console.WriteLine("You really are a good dog!"); | |
} | |
break; | |
case "cat": | |
Console.WriteLine($"Does the kitty own the house? {pet.Attributes["ownsTheHouse"]}"); | |
var cat = pet.Attributes.Deserialize<Cat>(lateBoundOptions); | |
if (cat.OwnsTheHouse) | |
{ | |
Console.WriteLine("It's your house."); | |
} | |
break; | |
} | |
} | |
stopwatch.Stop(); | |
Console.WriteLine($"Done in {stopwatch.ElapsedMilliseconds}ms"); | |
public class Person | |
{ | |
public string Name { get; set; } | |
public Pet[] Pets { get; set; } | |
} | |
public class Pet | |
{ | |
public string Name { get; set; } | |
public string Type { get; set;} | |
public JsonObject Attributes { get; set; } | |
} | |
public class Dog | |
{ | |
public bool IsAGoodDog { get; set;} | |
} | |
public class Cat | |
{ | |
public bool OwnsTheHouse { get; set; } | |
} | |
// Attempt to optimize deserialization | |
// https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/ | |
[JsonSerializable(typeof(Person), GenerationMode = JsonSourceGenerationMode.Metadata)] | |
internal partial class PersonJsonContext : JsonSerializerContext | |
{ | |
} | |
// SDK consumers could create their own and provide to us as perf optimization | |
[JsonSerializable(typeof(Dog), GenerationMode = JsonSourceGenerationMode.Metadata)] | |
[JsonSerializable(typeof(Cat), GenerationMode = JsonSourceGenerationMode.Metadata)] | |
internal partial class MyJsonContext : JsonSerializerContext | |
{ | |
} | |
/* OUTPUT | |
hello Nick | |
hello Moon you Cat! | |
Does the kitty own the house? true | |
It's your house. | |
hello Melody you Dog! | |
Are you a good dog? true | |
You really are a good dog! | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment