In a .NET Application, I have a set of values that are stored as a [Flags] enum
. I want to serialize these to json, but instead of having the result be an integer, I'd like to get an array of string for the flags that are active.
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 the Serialize()
method to return:
"{ Flags: [ "Val1", "Val4" ] }"
Instead of:
"{ Flags: 5 }"
You have to implement your own converter. Here's an example (a particularly dirty and hacky way of doing it, but it serves as a good demo):
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 enum like this:
[Flags]
[JsonConverter(typeof(FlagConverter))]
public enum F
{
Val1 = 1,
Val2 = 2,
Val4 = 4,
Val8 = 8
}
And your example serialisation code will now output this:
{"Flags":["Val1", "Val4"]}
Decorate your enum
[Flags]
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum F
{
Val1 = 1,
Val2 = 2,
Val4 = 4,
Val8 = 8
}
Output:
{"Flags":"Val1, Val4"}
I realise the JSON is not an array as in your question, wasn't sure if this was required since this is also valid JSON.
I used @DavidG's answer above, but needed an implementation for ReadJson. Here's what I put together:
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;
}
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;
}
Use Like
ConvertEnumsToJson<byte>(typeof(AnyEnum))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With