using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
public record Person(string FirstName, string LastName);
public sealed class PersonConverter : JsonConverter<Person>
record PersonDTO(string FirstName, string LastName, string Name);
public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
var dto = JsonSerializer.Deserialize<PersonDTO>(ref reader, options);
var oldNames = dto?.Name?.Split(' ', StringSplitOptions.RemoveEmptyEntries) ?? Enumerable.Empty<string>();
return new Person(dto.FirstName ?? oldNames.FirstOrDefault(), dto.LastName ?? oldNames.LastOrDefault());
public override void Write(Utf8JsonWriter writer, Person person, JsonSerializerOptions options)
JsonSerializer.Serialize(writer, person);
public static void Test()
foreach (var json in GetJson())
var options = new JsonSerializerOptions
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new PersonConverter() },
var person = JsonSerializer.Deserialize<Person>(json, options);
var json2 = JsonSerializer.Serialize(person, options);
Console.WriteLine(person);
Console.WriteLine(json2);
var person2 = JsonSerializer.Deserialize<Person>(json2, options);
Assert.AreEqual(person, person2);
static IEnumerable<string> GetJson() =>
@"{""lastName"":""LastName"",""firstName"":""FirstName""}",
@"{""name"":""Full Name""}",
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.Location.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];