![](/img/trans.png)
[英]C# Deserializing a Dictionary<(Enum,Enum),string> with JSON.NET
[英]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.