C # Json.NET Render Flags Enum as String Array

In a .NET application, I have a set of values ​​that are stored as [Flags] enum. I want to serialize them for json, but instead of the result being integer, I would like to get an array of strings for active flags.

So, if I have the following code

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

I want to return a method Serialize():

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

Instead:

"{ Flags: 5 }"
+11
source share
5 answers

You must implement your own converter. Here is an example (a particularly dirty and hacky way to do this, but it serves as a good demonstration):

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

Now decorate your listing as follows:

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

And your example serialization code now produces the following:

{"Flags":["Val1", "Val4"]}
+13
source

enum

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

:

{ "": "Val1, Val4" }

, JSON , , , , JSON.

+5

, OP, , , . @davidg, JSON ( 1 + 4 = 5):

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

, :

[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;
    }
}
+1
 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))
0

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

Source: https://habr.com/ru/post/1673721/


All Articles