Replacing StringCollection
with List<string>
as suggested in this answer by David L is the best solution to your problem, as StringCollection
is an untyped collection from .Net 1.1 and typed collections should always be preferred over untyped collections.
That being said, if you must deserialize a StringCollection
with System.Text.Json (e.g. because you are working with a legacy class you cannot rewrite), you may do so with the following simple JsonConverter<T>
:
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);
}
If your StringCollection
is large and you would like to avoid an intermediate List<String>
, modify Read()
as follows:
public override StringCollection? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException();
var sc = new StringCollection();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
sc.Add(reader.GetString());
return sc;
}
Then add the converter to JsonSerializerOptions
and deserialize as follows:
var options = new JsonSerializerOptions
{
Converters = { new StringCollectionConverter(), /* Add other converters here */ },
// Set other options below
WriteIndented = true,
};
var model = JsonSerializer.Deserialize<AclRecord>(json, options);
To configure the options for Asp.NET Core 3.1 and later, see How to set json serializer settings in asp.net core 3?.
Demo fiddles here and here.