Skip to content

Instantly share code, notes, and snippets.

@joaofbantunes
Created January 13, 2022 21:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joaofbantunes/37ebec5576b2b5a8624aa8a664dba113 to your computer and use it in GitHub Desktop.
Save joaofbantunes/37ebec5576b2b5a8624aa8a664dba113 to your computer and use it in GitHub Desktop.
ArrayOrObjectJsonConverter
<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>
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