C#Json.NET将标志枚举呈现为字符串数组

Car*_* G. 13 c# enums json json.net

在.NET应用程序中,我有一组存储为的值[Flags] enum.我想将这些序列化为json,但不是让结果是一个整数,我想得到一个活跃的标志字符串数组.

所以,如果我有以下代码

[Flags]
public enum F
{
    Val1 = 1,
    Val2 = 2,
    Val4 = 4,
    Val8 = 8

}

public class C
{        
    public F Flags { get; set; }
}

string Serialize() {
    return JsonConvert.SerializeObject(new C { Flags = F.Val1 | F.Val4 });
}
Run Code Online (Sandbox Code Playgroud)

我希望Serialize()方法返回:

"{ Flags: [ "Val1", "Val4" ] }"
Run Code Online (Sandbox Code Playgroud)

代替:

"{ Flags: 5 }"
Run Code Online (Sandbox Code Playgroud)

Dav*_*idG 16

你必须实现自己的转换器.这是一个例子(一种特别肮脏和黑客的方式,但它可以作为一个很好的演示):

public class FlagConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader,  Type objectType, Object existingValue, JsonSerializer serializer)
    {
        //If you need to deserialize, fill in the code here
        return null;
    }

    public override void WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
    {
        var flags = value.ToString()
            .Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries)
            .Select(f => $"\"{f}\"");

        writer.WriteRawValue($"[{string.Join(", ", flags)}]");
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在装饰你的枚举像这样:

[Flags]
[JsonConverter(typeof(FlagConverter))]
public enum F
{
    Val1 = 1,
    Val2 = 2,
    Val4 = 4,
    Val8 = 8
}
Run Code Online (Sandbox Code Playgroud)

您的示例序列化代码现在将输出:

{"Flags":["Val1", "Val4"]}
Run Code Online (Sandbox Code Playgroud)


Equ*_*lsk 8

装饰你的 enum

[Flags]
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum F
{
    Val1 = 1,
    Val2 = 2,
    Val4 = 4,
    Val8 = 8
}
Run Code Online (Sandbox Code Playgroud)

输出:

{“标志”:“ Val1,Val4”}

我意识到JSON不是您所提问题中的数组,因此不确定是否需要此数组,因为这也是有效的JSON。


小智 6

我在上面使用了 @DavidG 的答案,但需要 ReadJson 的实现。这是我整理的:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    int outVal = 0;
    if (reader.TokenType == JsonToken.StartArray)
    {
        reader.Read();
        while (reader.TokenType != JsonToken.EndArray)
        {
            outVal += (int)Enum.Parse(objectType, reader.Value.ToString());
            reader.Read();
        }
    }
    return outVal;
}
Run Code Online (Sandbox Code Playgroud)