![](/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.