使用Json.NET来(de)序列化DataContractJsonSerializer使用的结构中的字典?

有没有办法使用Json.NET进行(反)序列化,但继续使用DataContractJsonSerializer的字典序列化约定?

换句话说,有没有办法在这个结构中读写JSON:

 { "MyDict" : [ { "Key" : "One", "Value" : 1 }, { "Key" : "Two", "Value" : 2 } ] } 

使用这样的类(使用Json.NET属性):

 public class MyClass { public Dictionary MyDict { get; set; } } 

似乎Json.NET的KeyValuePairConverter可能会以某种方式提供帮助,但如果是这样,我找不到正确的方法来应用它。

我尝试使用[JsonProperty(ItemConverterType = typeof(KeyValuePairConverter))]归因MyDict , 这个页面甚至似乎暗示可以工作,但是在序列化期间添加这样的属性会导致ArgumentOutOfRangeException

你没错, KeyValuePairConverter似乎在这里不能正常工作。 没有深入研究Json.Net源代码,我只能推测为什么。 作为一种解决方法,您可以使用自己的自定义JsonConverter轻松完成此转换:

 class MyDictionaryConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(Dictionary)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JArray array = JArray.Load(reader); Dictionary dict = new Dictionary(); foreach (JObject obj in array.Children()) { string key = obj["Key"].ToString(); T val = obj["Value"].ToObject(); dict.Add(key, val); } return dict; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Dictionary dict = (Dictionary)value; JArray array = new JArray(); foreach (KeyValuePair kvp in dict) { JObject obj = new JObject(); obj.Add("Key", kvp.Key); obj.Add("Value", JToken.FromObject(kvp.Value)); array.Add(obj); } array.WriteTo(writer); } } 

使用[JsonConverter]属性将转换器应用于字典:

 public class MyClass { [JsonConverter(typeof(MyDictionaryConverter))] public Dictionary MyDict { get; set; } } 

这是一个简短的演示程序,显示转换器的运行情况(全程往返):

 class Program { static void Main(string[] args) { MyClass mc = new MyClass { MyDict = new Dictionary() }; mc.MyDict.Add("One", 1); mc.MyDict.Add("Two", 2); string json = JsonConvert.SerializeObject(mc, Formatting.Indented); Console.WriteLine(json); Console.WriteLine(); MyClass mc2 = JsonConvert.DeserializeObject(json); foreach (KeyValuePair kvp in mc2.MyDict) { Console.WriteLine(kvp.Key + " == " + kvp.Value); } } } 

以上输出:

 { "MyDict": [ { "Key": "One", "Value": 1 }, { "Key": "Two", "Value": 2 } ] } One == 1 Two == 2