Skip to content

Instantly share code, notes, and snippets.

@AlbertoMonteiro
Last active December 24, 2021 03:13
Show Gist options
  • Save AlbertoMonteiro/0a05a0fc74287ce857ee859bc93a0525 to your computer and use it in GitHub Desktop.
Save AlbertoMonteiro/0a05a0fc74287ce857ee859bc93a0525 to your computer and use it in GitHub Desktop.
CustomSerializeProperty
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
var person = new Person("Alberto", "JobInfo", new JobInfo("CSF", "Software Architect"));
var serializeOptions = new JsonSerializerOptions();
serializeOptions.Converters.Add(new BaseInfoConverter());
var firstJson = JsonSerializer.Serialize(person, serializeOptions);
var secondJson = JsonSerializer.Serialize(person with { InfoDescription = "ParentsInfo", OtherInfo = new ParentsInfo("Silvina", "José") }, serializeOptions);
Console.WriteLine(firstJson);
Console.WriteLine(secondJson);
Console.WriteLine("\n#########################################\n");
var firstPerson = JsonSerializer.Deserialize<Person>(firstJson, serializeOptions);
Console.WriteLine(firstPerson);
Console.WriteLine(firstPerson.OtherInfo is JobInfo);
Console.WriteLine(firstPerson.OtherInfo is ParentsInfo);
var secondPerson = JsonSerializer.Deserialize<Person>(secondJson, serializeOptions);
Console.WriteLine(secondPerson);
Console.WriteLine(secondPerson.OtherInfo is JobInfo);
Console.WriteLine(secondPerson.OtherInfo is ParentsInfo);
public record Person(string Name, string InfoDescription, object OtherInfo);
public record JobInfo(string Company, string Role);
public record ParentsInfo(string MotherName, string FatherName);
public class BaseInfoConverter : JsonConverter<Person>
{
public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (!JsonDocument.TryParseValue(ref reader, out var doc))
goto nothing;
var rootElement = doc.RootElement;
if (rootElement.TryGetProperty(nameof(Person.Name), out var nameProp) &&
rootElement.TryGetProperty(nameof(Person.InfoDescription), out var infoDescProp) &&
rootElement.TryGetProperty(nameof(Person.OtherInfo), out var otherInfoProp))
{
var name = nameProp.GetString()!;
var infoDesc = infoDescProp.GetString()!;
object baseInfo = infoDesc switch
{
nameof(JobInfo) => JsonSerializer.Deserialize<JobInfo>(otherInfoProp.GetRawText(), options)!,
nameof(ParentsInfo) => JsonSerializer.Deserialize<ParentsInfo>(otherInfoProp.GetRawText(), options)!
};
return new Person(name, infoDesc, baseInfo!);
}
nothing:
return default;
}
public override void Write(Utf8JsonWriter writer, [DisallowNull] Person value, JsonSerializerOptions options)
{
var cloneSettings = new JsonSerializerOptions(options);
cloneSettings.Converters.Remove(this);
JsonSerializer.Serialize(writer, value, cloneSettings);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment