繁体   English   中英

C# Json.NET Render 将枚举标记为字符串数组

[英]C# Json.NET Render Flags Enum as String Array

在 .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 });
}

我希望Serialize()方法返回:

"{ Flags: [ "Val1", "Val4" ] }"

代替:

"{ Flags: 5 }"

您必须实现自己的转换器。 这是一个例子(一种特别肮脏和骇人听闻的做法,但它作为一个很好的演示):

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;
    }
}

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

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

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

{"Flags":["Val1", "Val4"]}

装饰你的enum

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

输出:

{"Flags":"Val1, Val4"}

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

我在上面使用了@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;
}

这个答案与 OP 请求的序列化略有不同,但可能有用。 它基于@davidg 的解决方案,但序列化的 JSON 如下所示(对于 1+4=5):

{
    "Val1": true,
    "Val2": false,
    "Val4": true,
    "Val8": false  
}

标志枚举的装饰与 Davids 的回答相同:

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

但这里有一个不同的WriteJson方法和一个最小的工作例如ReadJson方法。

public class FlagConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        JObject jobject = JObject.FromObject(token);
        F result = 0;
        foreach (F f in Enum.GetValues(typeof(F)))
        {
            if (jobject[f.ToString()] != null && (bool)jobject[f.ToString()])
            {
                result |= f; // key is present and value is true ==> set flag
            }
        }
        return result;
    }

    public override void WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
    {
        JObject result = new JObject();
        F f = (F)value;
        foreach (F f in Enum.GetValues(typeof(F)))
        {
            result[f.ToString()] = status.HasFlag(f);
        }
        writer.WriteRawValue(JsonConvert.SerializeObject(result));
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}
 public static string ConvertEnumsToJson<T>(Type e)
        {

            var ret = "{";
            var index = 0;
            foreach (var val in Enum.GetValues(e))
            {
                if (index > 0)
                {
                    ret += ",";
                }
                var name = Enum.GetName(e, val);
                ret += name + ":" + ((T)val) ;
                index++;
            }
            ret += "}";
            return ret;

        }

使用喜欢

ConvertEnumsToJson<byte>(typeof(AnyEnum))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM