簡體   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