-
-
Save joaofbantunes/37ebec5576b2b5a8624aa8a664dba113 to your computer and use it in GitHub Desktop.
ArrayOrObjectJsonConverter
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
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>net6.0</TargetFramework> | |
<ImplicitUsings>enable</ImplicitUsings> | |
<Nullable>enable</Nullable> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="Spectre.Console" Version="0.43.0" /> | |
</ItemGroup> | |
</Project> |
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.Runtime.CompilerServices; | |
using System.Text.Json; | |
using System.Text.Json.Serialization; | |
using Spectre.Console; | |
const string Null = "null"; | |
const string EmptyArray = "[]"; | |
const string WrapperWithEmptyArray = @"{ | |
""items"": [] | |
}"; | |
const string Array = @"[ | |
{ | |
""id"": 123, | |
""text"": ""some text"" | |
}, | |
{ | |
""id"": 456, | |
""text"": ""some more text"" | |
} | |
]"; | |
const string Wrapper = @"{ | |
""items"": [ | |
{ | |
""id"": 123, | |
""text"": ""some text"" | |
}, | |
{ | |
""id"": 456, | |
""text"": ""some more text"" | |
} | |
] | |
}"; | |
var options = new JsonSerializerOptions | |
{ | |
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | |
WriteIndented = true | |
}; | |
options.Converters.Add(new ArrayOrObjectJsonConverter<SomeDto>()); | |
DeserializeAndPrint(Null); | |
DeserializeAndPrint(EmptyArray); | |
DeserializeAndPrint(WrapperWithEmptyArray); | |
DeserializeAndPrint(Array); | |
DeserializeAndPrint(Wrapper); | |
void DeserializeAndPrint(string json, [CallerArgumentExpression("json")] string title = "") | |
{ | |
var result = JsonSerializer.Serialize(JsonSerializer.Deserialize<IReadOnlyCollection<SomeDto>>(json, options), options); | |
AnsiConsole.Write(new Table() | |
.AddColumn(new TableColumn(title)) | |
.AddRow(new Table {Alignment = Justify.Center} | |
.AddColumn("original") | |
.AddRow(new Text(json))) | |
.AddRow(new Text("↓↓↓↓↓") {Alignment = Justify.Center}) | |
.AddRow(new Table { Alignment = Justify.Center } | |
.AddColumn("deserialized") | |
.AddRow(new Text(result)))); | |
} | |
public record SomeDto(int Id, string Text); | |
public class ArrayOrObjectJsonConverter<T> : JsonConverter<IReadOnlyCollection<T>> | |
{ | |
public override IReadOnlyCollection<T>? Read( | |
ref Utf8JsonReader reader, | |
Type typeToConvert, | |
JsonSerializerOptions options) | |
=> reader.TokenType switch | |
{ | |
JsonTokenType.StartArray => JsonSerializer.Deserialize<T[]>(ref reader, options), | |
JsonTokenType.StartObject => JsonSerializer.Deserialize<Wrapper>(ref reader, options)?.Items, | |
_ => throw new JsonException() | |
}; | |
public override void Write(Utf8JsonWriter writer, IReadOnlyCollection<T> value, JsonSerializerOptions options) | |
=> JsonSerializer.Serialize(writer, (object?) value, options); | |
private record Wrapper(T[] Items); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment