Json序列化字典的问题

每当我尝试序列化字典时,我都会得到exception:

System.ArgumentException: Type 'System.Collections.Generic.Dictionary`2[[Foo.DictionarySerializationTest+TestEnum, Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' is not supported for serialization/deserialization of a dictionary, keys must be strings or object 

我的测试用例是:

 public class DictionarySerializationTest { public enum TestEnum { A, B, C } //tried with numbers, too: public enum TestEnum { A = 1, B = 2, C = 3 } public void SerializationTest() { Dictionary data = new Dictionary(); data.Add(TestEnum.A, 1); data.Add(TestEnum.B, 2); data.Add(TestEnum.C, 3); JavaScriptSerializer serializer = new JavaScriptSerializer(); String result = serializer.Serialize(data); // Throws } public void SerializationToObjectTest() { Dictionary data = new Dictionary(); data.Add(Enum.ToObject(typeof(TestEnum), TestEnum.A), 1); data.Add(Enum.ToObject(typeof(TestEnum), TestEnum.B), 2); data.Add(Enum.ToObject(typeof(TestEnum), TestEnum.C), 3); JavaScriptSerializer serializer = new JavaScriptSerializer(); String result = serializer.Serialize(data); // Throws } public void SerializationStringTest() { Dictionary data = new Dictionary(); data.Add(TestEnum.A.ToString(), 1); data.Add(TestEnum.B.ToString(), 2); data.Add(TestEnum.C.ToString(), 3); JavaScriptSerializer serializer = new JavaScriptSerializer(); String result = serializer.Serialize(data); // Succeeds } } 

当然,每当我在词典中输入内容时,我都可以使用.ToString(),但由于它在性能相关的方法中经常使用,我宁愿使用枚举。

我唯一的解决方案是在进入性能关键区域之前使用.ToString()和转换,但这是笨拙的,我将不得不改变我的代码结构只是为了能够序列化数据。

有没有人知道如何将字典序列化为

我使用System.Web.Script.Serialization.JavaScriptSerializer进行序列化。

更新:

我现在切换到Dictionary它工作但我希望有人显示解决方案,因为我不喜欢使用字符串代替类型安全枚举。

我知道现在已经很晚了,但也许其他人可以在将来使用它。 您可以使用LINQ实现所需:

 Dictionary data = new Dictionary(); data.Add(TestEnum.A, 1); data.Add(TestEnum.B, 2); data.Add(TestEnum.C, 3); JavaScriptSerializer serializer = new JavaScriptSerializer(); Dictionary dataToSerialize = data.Keys.ToDictionary(p => p.ToString(), p => data[p]); string dataSerialized = serializer.Serialize(dataToSerialize); 

使用Newtonsoft(Newtonsoft.Json.dll)序列化Dictionary对象,你会没事的。 这是一个受欢迎的第三方库,您必须下载并包含在您的项目中作为参考。

见下面的例子:

 var _validationInfos = new Dictionary(); var serializedData = JsonConvert.SerializeObject(_validationInfos); 

我认为您遇到了麻烦,因为TestEnum被声明为private enum 。 尝试将其标记为public enum 。 序列化程序需要能够通过reflection找到您的枚举,以便序列化它。

同样根据文档 ,枚举必须具有整数值。 所以你可能想写:

 public enum TestEnum { A = 1, B = 2, C =3 } 

此外,文档说这个枚举将在序列化期间被映射到其对应的整数值。 因此,根据您在另一端所做的事情, String可能更具表现力,更易于使用。

例外情况说“键必须是字符串或对象”,所以请尝试

 data.Add(Enum.ToObject(typeof(TestEnum), TestEnum.A)); data.Add(Enum.ToObject(typeof(TestEnum), TestEnum.B)); data.Add(Enum.ToObject(typeof(TestEnum), TestEnum.C)); 

我没有测试它,只是一个猜测。

我已创建JavaScriptSerializer扩展DeserializeDictionary-请参阅http://geekswithblogs.net/mnf/archive/2011/06/03/javascriptserializer-extension-deserializedictionarytkey-tvalue.aspx

 public static Dictionary DeserializeDictionary(this JavaScriptSerializer jss, string jsonText) { var dictWithStringKey = jss.Deserialize>(jsonText); var dict=dictWithStringKey.ToDictionary(de => jss.ConvertToType(de.Key),de => de.Value); return dict; }