JsonConvert.DeserializeObject() 无法正确反序列化字符串
JsonConvert.DeserializeObject() cannot deserialize the string properly
我正在尝试将此词典存储为 json:
Dictionary<string, Dictionary<string, Word>> _cateList;
//class Word
public Word{
private string _title;
public string Title
{
get
{
return _title;
}
set
{
if (string.IsNullOrEmpty(value)){
throw new Exception();
}
_title = value;
}
}
//key:category, value:definition
private Dictionary<string,string> _categorizedDefinition;
public Dictionary<string, string> CategorizedDefinition
{
get
{
return _categorizedDefinition;
}
}
}
所以基本上有 3 个字典在彼此里面。
首先,我用 JsonConvert.Serialize 的一些示例代码序列化字典,输出 json 文件如下所示:
//json code
{
"biology": {
"biology": {
"Title": "Tree",
"CategorizedDefinition": {
"Biology": "A plant"
}
}
}
}
//c# code
Dictionary<string, string> temp = new Dictionary<string, string>()
{ {"Biology", "A plant" } };
Word wd = new Word("Tree", temp);
_cateList.Add("biology", new Dictionary<string, Word>()
{
{"biology", wd }
});
但是当我使用这些代码反序列化 json:
_cateList = await DataJsonHandler.LoadFromJsonFile();
//method code
public async static Task<Dictionary<string, Dictionary<string, Word>>> LoadFromJsonFile()
{
Dictionary<string, Dictionary<string, Word>> tempDic;
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("CategorizedWords.json");
using (StreamReader sr = new StreamReader(awaitfile.OpenStreamForReadAsync()))
{
//this lines got the same string in the original json file
string lines = sr.ReadToEnd();
tempDic = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Word>>>(lines);
}
return tempDic;
}
再次序列化,得到:
{
"biology": {
"biology": {
"Title": "Tree",
"CategorizedDefinition": null
}
}
}
不确定这里发生了什么导致 Word 对象中的字典消失,我是不是漏掉了什么?
您在 CategorizedDefinition
上忘记了 setter。您需要它以便 newtonsoft 在反序列化时设置 属性 值。
public Dictionary<string, string> CategorizedDefinition
{
get => _categorizedDefinition;
set => _categorizedDefinition = value; // < --magic here
}
但是由于您使用的是 Word
class 的构造函数,您可能会忘记在该构造函数中设置 _categorizedDefinition。这样的事情会做:
// constructor
public Word(string title, Dictionary<string, string> categorizedDefinition)
{
// ignoring title for now, because it already works.
this._categorizedDefinition = categorizedDefinition;
}
private Dictionary<string, string> _categorizedDefinition
public Dictionary<string, string> CategorizedDefinition
{
get => _categorizedDefinition;
set => _categorizedDefinition = value;
}
我正在尝试将此词典存储为 json:
Dictionary<string, Dictionary<string, Word>> _cateList;
//class Word
public Word{
private string _title;
public string Title
{
get
{
return _title;
}
set
{
if (string.IsNullOrEmpty(value)){
throw new Exception();
}
_title = value;
}
}
//key:category, value:definition
private Dictionary<string,string> _categorizedDefinition;
public Dictionary<string, string> CategorizedDefinition
{
get
{
return _categorizedDefinition;
}
}
}
所以基本上有 3 个字典在彼此里面。 首先,我用 JsonConvert.Serialize 的一些示例代码序列化字典,输出 json 文件如下所示:
//json code
{
"biology": {
"biology": {
"Title": "Tree",
"CategorizedDefinition": {
"Biology": "A plant"
}
}
}
}
//c# code
Dictionary<string, string> temp = new Dictionary<string, string>()
{ {"Biology", "A plant" } };
Word wd = new Word("Tree", temp);
_cateList.Add("biology", new Dictionary<string, Word>()
{
{"biology", wd }
});
但是当我使用这些代码反序列化 json:
_cateList = await DataJsonHandler.LoadFromJsonFile();
//method code
public async static Task<Dictionary<string, Dictionary<string, Word>>> LoadFromJsonFile()
{
Dictionary<string, Dictionary<string, Word>> tempDic;
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("CategorizedWords.json");
using (StreamReader sr = new StreamReader(awaitfile.OpenStreamForReadAsync()))
{
//this lines got the same string in the original json file
string lines = sr.ReadToEnd();
tempDic = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Word>>>(lines);
}
return tempDic;
}
再次序列化,得到:
{
"biology": {
"biology": {
"Title": "Tree",
"CategorizedDefinition": null
}
}
}
不确定这里发生了什么导致 Word 对象中的字典消失,我是不是漏掉了什么?
您在 CategorizedDefinition
上忘记了 setter。您需要它以便 newtonsoft 在反序列化时设置 属性 值。
public Dictionary<string, string> CategorizedDefinition
{
get => _categorizedDefinition;
set => _categorizedDefinition = value; // < --magic here
}
但是由于您使用的是 Word
class 的构造函数,您可能会忘记在该构造函数中设置 _categorizedDefinition。这样的事情会做:
// constructor
public Word(string title, Dictionary<string, string> categorizedDefinition)
{
// ignoring title for now, because it already works.
this._categorizedDefinition = categorizedDefinition;
}
private Dictionary<string, string> _categorizedDefinition
public Dictionary<string, string> CategorizedDefinition
{
get => _categorizedDefinition;
set => _categorizedDefinition = value;
}