Skip to content

Instantly share code, notes, and snippets.

@akunzai
Last active November 10, 2023 14:59
Show Gist options
  • Save akunzai/79fc7a93afcb93955f57bde8bd388000 to your computer and use it in GitHub Desktop.
Save akunzai/79fc7a93afcb93955f57bde8bd388000 to your computer and use it in GitHub Desktop.
JsonConverter for list of enum string
using System.Reflection;
namespace System.Text.Json.Serialization;
/// https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/converters-how-to
public class ListOfEnumStringConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType)
{
return false;
}
return typeToConvert.GetGenericTypeDefinition() == typeof(IList<>) && typeToConvert.GetGenericArguments()[0].IsEnum;
}
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
Type enumType = typeToConvert.GetGenericArguments()[0];
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
typeof(ListOfEnumStringConverterInner<>).MakeGenericType(enumType),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: null,
culture: null)!;
return converter;
}
private sealed class ListOfEnumStringConverterInner<T> :
JsonConverter<List<T>> where T : struct, Enum
{
public override List<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
{
throw new JsonException();
}
var items = new List<T>();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray)
{
return items;
}
// Get the item.
string? value = reader.GetString();
// For performance, parse with ignoreCase:false first.
if (!Enum.TryParse(value, ignoreCase: false, out T item) &&
!Enum.TryParse(value, ignoreCase: true, out item))
{
throw new JsonException(
$"Unable to convert \"{value}\" to Enum \"{typeof(T)}\".");
}
items.Add(item);
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, List<T> items, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var item in items)
{
writer.WriteStringValue(item.ToString());
}
writer.WriteEndArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment