using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json.Serialization;
using System.Text.Json.Nodes;
public class ObjectAsNameValueArrayConverter<T> : DefaultConverterFactory<T>
public NameValuePair(string name, JsonNode value) { this.name = name; this.value = value; }
public string name { get; set; }
public JsonNode value { get; set;}
protected override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions modifiedOptions)
if (reader.TokenType == JsonTokenType.StartArray)
var array = JsonSerializer.Deserialize<List<NameValuePair>>(ref reader, modifiedOptions)!;
var obj = new JsonObject(array.Select(p => new KeyValuePair<string, JsonNode>(p.name, p.value)));
return obj.Deserialize<T>(modifiedOptions);
return base.Read(ref reader, typeToConvert, modifiedOptions);
protected override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions modifiedOptions)
var node = JsonSerializer.SerializeToNode(value, modifiedOptions);
if (node is JsonObject obj)
JsonSerializer.Serialize(writer, obj.Select(p => new NameValuePair(p.Key, p.Value)));
public abstract class DefaultConverterFactory<T> : JsonConverterFactory
class DefaultConverter : JsonConverter<T>
readonly JsonSerializerOptions modifiedOptions;
readonly DefaultConverterFactory<T> factory;
public DefaultConverter(JsonSerializerOptions modifiedOptions, DefaultConverterFactory<T> factory)
this.modifiedOptions = modifiedOptions;
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { factory.Write(writer, value, modifiedOptions); }
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return factory.Read(ref reader, typeToConvert, modifiedOptions); }
public override bool CanConvert(Type typeToConvert) { return typeof(T).IsAssignableFrom(typeToConvert); }
protected virtual JsonSerializerOptions ModifyOptions(JsonSerializerOptions options) { return options.CopyAndRemoveConverter(this.GetType()); }
protected virtual T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions modifiedOptions) { return (T)JsonSerializer.Deserialize(ref reader, typeToConvert, modifiedOptions); }
protected virtual void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions modifiedOptions) { JsonSerializer.Serialize(writer, value, modifiedOptions); }
public override bool CanConvert(Type typeToConvert) { return typeof(T) == typeToConvert; }
public sealed override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { return new DefaultConverter(ModifyOptions(options), this); }
public static class JsonSerializerExtensions
public static JsonSerializerOptions CopyAndRemoveConverter(this JsonSerializerOptions options, Type converterType)
var copy = new JsonSerializerOptions(options);
for (var i = copy.Converters.Count - 1; i >= 0; i--)
if (copy.Converters[i].GetType() == converterType)
copy.Converters.RemoveAt(i);
public class DateTimeConverterForCustomStandardFormatR : JsonConverter<DateTime>
static readonly DateTime UnixEpoch = DateTime.UnixEpoch;
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
return UnixEpoch.AddMilliseconds(reader.GetInt64());
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
long ms = Convert.ToInt64((value - UnixEpoch).TotalMilliseconds);
writer.WriteNumberValue(ms);
[JsonPropertyName("points")]
[System.Text.Json.Serialization.JsonConverter(typeof(ObjectAsNameValueArrayConverter<Point>))]
public Point Point { get; set; }
public string title { get; set; }
public string category { get; set; }
[System.Text.Json.Serialization.JsonConverter(typeof(DateTimeConverterForCustomStandardFormatR))]
public DateTime? created { get; set; }
public int? version { get; set; }
public static void Test()
Console.WriteLine("DateTime.UnixEpoch.Ticks = {0}", DateTime.UnixEpoch.Ticks);
var myViews = JsonSerializer.Deserialize<MyViews>(json);
var json2 = JsonSerializer.Serialize(myViews, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine("Re-serialized {0}:", myViews);
Console.WriteLine(json2);
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Convert.ToInt64(0.999) = {0}", Convert.ToInt64(0.999));
Console.WriteLine("(long)(0.999) = {0}\n", (long)(0.999));
Console.WriteLine("Failed with unhandled exception: ");