使用自定义枚举JSON转换器

gt0wga4j  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(174)

我正在寻找创建一个自定义JSON转换器对我的C#应用程序。当我示例化一个新的类,我不能让它泛型。

班级:

using System.Text.Json;
using System.Text.Json.Serialization;

public class Converter<T> : JsonConverter<T> where T : Enum
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string? data = reader.GetString();
        return data.GetEnum<T>()!;
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        writer.WriteString(value.GetDescription<T>());
    }
}
fzsnzjdm

fzsnzjdm1#

您应该使用工厂模式为遇到的每种枚举类型制造特定的转换器:

public class CustomEnumConverter : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum; // Add anything additional here such as typeToConvert.IsEnumWithDescription() to check for description attributes.

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
        (JsonConverter)Activator.CreateInstance(typeof(CustomConverter<>).MakeGenericType(typeToConvert))!;

    class CustomConverter<T> : JsonConverter<T> where T : struct, Enum
    {
        public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
            reader.GetString()!.GetEnumValue<T>()!;

        public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) =>
            writer.WriteStringValue(value.GetDescription<T>());
    }
}

工厂转换器可以直接应用于属性,只要工厂可以返回属性类型的转换器即可,因此无需将内部转换器设置为公共:

public class Model
{
    [JsonConverter(typeof(CustomEnumConverter))]
    public SomeEnum? SomeEnum { get; set; }
}

实际上,内置的JsonStringEnumConverter也是通过工厂模式实现的。
演示小提琴here

xuo3flqw

xuo3flqw2#

您应该检查已经存在的JsonStringEnumConverter:https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonstringenumconverter
x.JsonSerializerOptions.转换器.Add(新建的JsonStringEnumConverter());

相关问题