using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using Newtonsoft.Json.Linq;
using System.Text.Json.Serialization;
[JsonConverter(typeof(AvatarConverter))]
public Byte[] Data { get; set; } = null;
class AvatarConverter : JsonConverter<AvatarImage>
class AvatarDTO { public string Data { get; set; } }
public override AvatarImage Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
var dto = JsonSerializer.Deserialize<AvatarDTO>(ref reader, options);
var index = dto.Data?.IndexOf(',') ?? -1;
return new AvatarImage { Data = dto.Data == null ? null : Convert.FromBase64String(index < 0 ? dto.Data : dto.Data.Remove(0, index + 1)) };
public override void Write(Utf8JsonWriter writer, AvatarImage value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, new { Data = value.Data }, options);
public static void Test()
var avatar1 = new AvatarImage
Data = Enumerable.Repeat((byte)1, 10).ToArray(),
var json1 = JsonSerializer.Serialize(avatar1);
Console.WriteLine(json1);
var token = JToken.Parse(json1);
token["Data"] = "header,"+(string)token["Data"];
var json11 = token.ToString(Newtonsoft.Json.Formatting.None);
Console.WriteLine(json11);
var avatar2 = JsonSerializer.Deserialize<AvatarImage>(json11);
var json2 = JsonSerializer.Serialize(avatar2);
Console.WriteLine(json2);
Assert.IsTrue(Enumerable.SequenceEqual(avatar1.Data, avatar2.Data));
Assert.AreEqual(json1, json2);
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];