2017-03-08 55 views
2

我試着去序列化我的字典裏,看起來像一本字典:序列化和反序列化包含類關鍵字

private Dictionary<MetaDataKey, User> _dictionary; 

其中MetaDataKey和用戶類看起來像這樣:

internal class User 
{ 
    public string UserName { get; set; } 
    public string UserPassword { get; set; } 
    public List<Account> Accounts { get; set; } 
} 
internal class Account 
{ 
    public string Subject { get; set; } 
    public string AccName { get; set; } 
    public string AccPass { get; set; } 
    public List<string> Notes { get; set; } 
} 
internal class MetaDataKey 
{ 
    public string Name { get; set; } 
    public string Password { get; set; } 
} 

我想從這樣的json文件保存\加載字典到\:

private void DictionaryInit() 
    { 
     //gets the dictionary file if exists, create an empty one if not. 
     string path = Directory.GetCurrentDirectory() + "\\dic.json"; 
     if (!File.Exists(path)) 
     { 
      _dictionary = new Dictionary<MetaDataKey, User>(); 
      return; 
     } 
     using (StreamReader r = new StreamReader(path)) 
     { 
      string json = r.ReadToEnd(); 
      _dictionary = JsonConvert.DeserializeObject<Dictionary<MetaDataKey, User>>(json); 
     } 
    } 

    public void DictionarySave() 
    { 
     //save the dictionary into dic.json file 
     string path = Directory.GetCurrentDirectory() + "\\dic.json"; 
     string json = JsonConvert.SerializeObject(_dictionary); 
     File.WriteAllText(path, json); 
    } 

我在裝載一個新的記錄到字典,並試圖挽救它,我得到:

{"WpfApplication2.MetaDataKey":{"UserName":"Enter Name","UserPassword":"Enter Password","Accounts":null}} 

代替:

{"WpfApplication2.MetaDataKey":{"Name":"Enter Name","Password":"Enter Password"},"WpfApplication2.User":{"UserName":"Enter Name","UserPassword":"Enter Password","Accounts":null}} 

,你可以告訴我得到在MetaDataKey類用戶的領域。 即使我修復它manualy我仍然得到異常:

An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code 

當我試圖加載非空文件。 總之,2個問題: 1.糟糕的json節約。 2.壞JSON裝載

+0

我們可以看到一個json文件包含的例子嗎? – maccettura

+0

第一次是空的,我添加一個記錄後,我得到這個文件:{「WpfApplication2.MetaDataKey」:{「UserName」:「Enter Name」,「UserPassword」:「Enter Password」,「Accounts」: null}} (與iive發佈相同) –

+0

它看起來像Newtonsoft JSON序列化程序使用鍵對象的ToString表示形式作爲鍵。默認的ToString表示是完整的類名(= namespace.classname)。 – ckuri

回答

0

嘗試使用JsonProperty屬性類似如下:

internal class User 
{ 

[JsonProperty("UserName ")] 
public string UserName { get; set; } 

[JsonProperty("UserPassword")] 
public string UserPassword { get; set; } 

[JsonProperty("Accounts ")] 
public List<Account> Accounts { get; set; } 
} 
+0

我得到了同樣的結果。 –

+0

請參閱本[指南](http://www.newtonsoft.com/json/help/html/SerializationGuide.htm) –

0

Json.Net文檔:

當序列化的字典,所述字典的鍵被轉換字符串並用作JSON對象屬性名稱。爲關鍵字編寫的字符串可以通過覆蓋鍵類型的ToString()或通過實現TypeConverter來定製。在反序列化字典時,TypeConverter還支持再次轉換自定義字符串。

你有兩個選擇:

  1. 如文檔建議:爲您創造MetaDataKey一個TypeConverter與屬性([TypeConverter(typeof(MetaDataKeyConverter))])將其鏈接 - 這是不平凡的,你必須將MetaDataKey轉換爲json字符串自己,並從字符串反序列化。
  2. 爲字典創建JsonConverter並在JsonConvert.SerializeObjectJsonConvert.DeserializeObject方法中使用它。
  3. 最簡單的件事你可以做的是詞典]轉換爲List<KeyValuePair<MetaData,User>>這是很容易爲_dictionary.ToList()
    所以序列化:

    string json = JsonConvert.SerializeObject(_dictionary.ToList()); 
    

    而對於反序列化:

    _dictionary = 
          JsonConvert.DeserializeObject<List<KeyValuePair<MetaDataKey, User>>>(json) 
          .ToDictionary(kv => kv.Key, kv => kv.Value); 
    

對於大多數情況下,我會選擇選項3