using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text.Json.Serialization;
public class StringCollectionConverter : JsonConverter<StringCollection>
public override StringCollection? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
JsonSerializer.Deserialize<List<string>>(ref reader, options)?.Aggregate(new StringCollection(), (sc, s) => { sc.Add(s); return sc; });
public override void Write(Utf8JsonWriter writer, StringCollection value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, value.Cast<string>(), options);
public Dictionary<string, Dictionary<string, Dictionary<string, StringCollection>>> ACL { get; set; }
public static void Test()
public static void TestBasic()
var sc = new StringCollection();
sc.AddRange(new []{"a", "b", null!, "c\n\0c" });
var options = new JsonSerializerOptions { Converters = { new StringCollectionConverter() } };
var json = JsonSerializer.Serialize(sc, options);
var sc2 = JsonSerializer.Deserialize<StringCollection>(json, options);
var json2 = JsonSerializer.Serialize(sc2);
Console.WriteLine(json2);
Assert.AreEqual(json, json2);
Assert.That(sc.Cast<string>().SequenceEqual(sc2!.Cast<string>()));
static void TestAclRecord()
var options = new JsonSerializerOptions
Converters = { new StringCollectionConverter(), },
var model = JsonSerializer.Deserialize<AclRecord>(json, options);
var json2 = JsonSerializer.Serialize(model, options);
Console.WriteLine("Re-serialized {0};", model);
Console.WriteLine(json2);
Assert.AreEqual(json, json2);
static string GetJson() => @"{
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("Failed with unhandled exception: ");