2010-05-23 50 views
12

問題每當我試圖序列字典我得到異常:使用JSON序列化字典<Enum, Int32>

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<TestEnum, Int32> data = new Dictionary<TestEnum, Int32>(); 

    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<object, Int32> data = new Dictionary<object, Int32>(); 

    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<String, Int32> data = new Dictionary<String, Int32>(); 

    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(中)每當我在Dictionary中輸入一些內容,但由於它在性能相關的方法中經常使用,我寧願使用枚舉。

我唯一的解決方案是使用的ToString(),並進入業績的關鍵區域之前轉換,但就是麻煩,我不得不改變我的代碼結構,只是爲了能夠序列化的數據。

有沒有人有一個想法如何,我可以序列化字典作爲<Enum, Int32>

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

UPDATE:

我現在切換到Dictionary<String, Int32>和它的作品,但我希望有人顯示解決方案,我真的不喜歡到位類型安全枚舉的使用字符串。

+0

的可能重複(HTTP://計算器。COM /問題/ 5597349 /怎麼辦,我變頻-A-字典至A-JSON字符串,在-C) – 2014-03-07 16:39:57

回答

18

我知道它的晚,但也許別人可以在將來使用它。你可以實現你需要使用LINQ是什麼:

Dictionary<TestEnum, Int32> data = new Dictionary<TestEnum, Int32>(); 

data.Add(TestEnum.A, 1); 
data.Add(TestEnum.B, 2); 
data.Add(TestEnum.C, 3); 

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
Dictionary<string, Int32> dataToSerialize = data.Keys.ToDictionary(p => p.ToString(), p => data[p]); 
string dataSerialized = serializer.Serialize(dataToSerialize); 
+0

爲時不晚......在2016年 – 2016-07-29 11:13:25

+0

還是有幫助的我仍然會建議使用Json.NET因爲它的JavaScriptSerializer類文檔中指出:https://msdn.microsoft.com/en-us/library/system.web.script .serialization.javascriptserializer(v = vs.110)的.aspx – kimbaudi 2017-11-15 13:58:35

0

我認爲你有麻煩,因爲TestEnum被聲明爲private enum。嘗試將其標記爲public enum。序列化程序需要能夠通過反射來查找您的枚舉以序列化它。

此外,根據本Docs,所述枚舉必須具有整數值。所以,你可能想要寫:

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

此外,文檔說,這枚舉只會得到序列化映射過程中其相應的整數值。因此,根據你在另一端做什麼,String可能更具表現力,更容易處理。

+0

感謝您的建議,但改變枚舉公衆和增加整數值沒有變化任何東西。 – dbemerlin 2010-05-23 19:06:23

0

異常說「鍵必須是字符串或對象」,所以嘗試

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

我沒有,雖然測試它,只是一個猜測。

+0

它似乎並不接受所有對象類型,錯誤仍然相同。 (還是)感謝你的建議。 – dbemerlin 2010-05-23 19:07:15

0

我創建JavaScriptSerializer擴展DeserializeDictionary-看到http://geekswithblogs.net/mnf/archive/2011/06/03/javascriptserializer-extension-deserializedictionarytkey-tvalue.aspx

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

使用Newtonsoft(Newtonsoft.Json.dll)序列化Dictionary對象,你會被罰款。這是一個受歡迎的第三方庫,您必須下載並將其作爲參考包含在您的項目中。

見下面的例子:我如何轉換字典JSON字符串在C#]

var _validationInfos = new Dictionary<ImportField, ValidationInfo>(); 
var serializedData = JsonConvert.SerializeObject(_validationInfos); 
+0

這些天來,即使微軟建議使用Newtonsoft JSON庫:https://msdn.microsoft.com/en-us/library/system.web.script.serialization。 javascriptserializer(v = vs.110)的.aspx – Mr47 2017-08-22 07:14:23