c#反序列化字典<(Enum,Enum),string>与JSON.NET



我一直在努力用Json.Net中的Enum元组键反序列化字典。主要问题是反序列化器无法将值转换回指定的Enum元组,无论它是Enum在Json中的字符串表示还是整数表示。

我已经尝试了这些解决方案,但都不起作用:

  1. https://stackoverflow.com/a/59310390
  2. https://gist.github.com/SteveDunn/e355b98b0dbf5a0209cb8294f7fffe24

试着写我自己的自定义转换器,WriteJson部分工作,但我甚至不能停止ReadJson函数与断点,看看里面发生了什么。

我很乐意在这个问题上得到一些帮助。也许有人已经有解决办法了。

JSON是这样的:

{
   "DictionaryProperty":{
      "(EnumType1Value1, EnumType2Value1)":"New",
      "(EnumType1Value1, EnumType2Value1)":"Old",
      "(EnumType1Value2, EnumType2Value1)":"Newer",
      "(EnumType1Value2, EnumType2Value2)":"Older"
}

这是我得到的错误:

"无法将字符串'(EnumType1Value1, EnumType2Value1)'转换为字典键类型'System.ValueTuple ' 2[EnumType1,EnumType2]'">

这是我编写的自定义转换器:

public class CustomDictionaryConverter : JsonConverter<Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>>
{
    public override void WriteJson(JsonWriter writer, Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, ((Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>)value).ToList());
    }
    public override Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> ReadJson(
        JsonReader reader
        , Type objectType
        , Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> existingValue
        , bool hasExistingValue
        , JsonSerializer serializer)
    {
        Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> tempdict = new Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>();
        var temp = serializer.Deserialize<Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>[]>(reader)[0];
        tempdict = (Dictionary<(EnumType1 Enum1, EnumType2  Enum2), string>)temp;
        return tempdict;
    }
}

有点手动(并且缺乏体面的错误检查),但适用于您指定的json序列化&反序列化

public class CustomDictionaryConverter : JsonConverter<Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>>
{
    public override void WriteJson(JsonWriter writer, Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        foreach(var kv in value)
        {
            writer.WritePropertyName($"({kv.Key.Enum1.ToString()},{kv.Key.Enum2.ToString()})");
            writer.WriteValue(kv.Value);
        }
        writer.WriteEndObject();
    }
    public override Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> ReadJson(
        JsonReader reader
        , Type objectType
        , Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> existingValue
        , bool hasExistingValue
        , JsonSerializer serializer)
    {
        Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string> tempdict = new Dictionary<(EnumType1 Enum1, EnumType2 Enum2), string>();
        JObject jObject = JObject.Load(reader);
        foreach(var kv in ((IEnumerable<KeyValuePair<string, JToken>>)jObject)) 
        {
            var keys = kv.Key.Replace("(","").Replace(")","").Split(",");
            var key1 = Enum.Parse<EnumType1>(keys[0]);
            var key2 = Enum.Parse<EnumType2>(keys[1]);
            var value = kv.Value.ToString();
            tempdict.Add((key1,key2),value);
        }
        return tempdict;
    }
}

实例:https://dotnetfiddle.net/w85HgK

最新更新