在.NET应用程序中,我有一组存储为ContT
的值。我想将这些序列化为json,但是我没有将结果作为整数,而是希望为活动的标志获取一个字符串数组。
所以,如果我有以下代码
[Flags] enum
我希望[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" ] }"
答案 0 :(得分:12)
您必须实施自己的转换器。这是一个例子(一种特别肮脏和黑客的方式,但它可以作为一个很好的演示):
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"]}
答案 1 :(得分:5)
装饰你的enum
[Flags]
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum F
{
Val1 = 1,
Val2 = 2,
Val4 = 4,
Val8 = 8
}
输出:
{“Flags”:“Val1,Val4”}
我意识到JSON不是你问题中的数组,不确定这是否是必需的,因为这也是有效的JSON。
答案 2 :(得分:1)
此答案与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;
}
}
答案 3 :(得分:1)
我使用了@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;
}
答案 4 :(得分:0)
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))