Newtonsoft.JSON 在反序列化数组中用双引号括起来的对象时阻塞
Newtonsoft.JSON chokes on deserializing object that's surrounded by double quotes in an array
我正在使用 Newtonsoft.JSON 序列化 List<UserDataJson>
,然后写入文件。这是 class:
private class UserDataJson
{
public UserDataJson() { }
public UserDataJson(string path)
{
Location = path;
Opacity = 1;
}
public UserDataJson(IUserData userData)
{
Location = userData.Location;
Opacity = userData.Opacity;
}
public string Location { get; set; }
public double Opacity { get; set; }
}
序列化写入的代码:
private static readonly string _userDataFile = Path.Combine(_programDataFolder, "userdata.json");
...
public void SaveData(IReadOnlyCollection<IUserData> userData)
{
File.WriteAllText(_userDataFile, JsonConvert.SerializeObject(userData.Select(Serialize).ToList(), Formatting.Indented));
}
private static string Serialize(IUserData userData) => JsonConvert.SerializeObject(new UserDataJson(userData));
对于一个元素,这会生成一个如下所示的 _userDataJson
文件:
[
"{\"Location\":\"C:\\Users\\me\\Documents\\test.txt\",\"Opacity\":1.0}"
]
然而,当我尝试反序列化时,我得到一个 JsonSerializationException
:
反序列化:
JsonConvert.DeserializeObject<List<UserDataJson>>(File.ReadAllText(_userDataFile).Replace("\\", "\");
异常:
{"Error converting value \"{\"Location\":\"C:\Users\me\Documents\test.txt\",\"Opacity\":1.0}\" to type 'Company.App.Wpf.MainWindow.UserDataService+UserDataJson'. Path '[0]', line 2, position 73."}
内部异常:
"Could not cast or convert from System.String to Company.App.Wpf.MainWindow.UserDataService+UserDataJson."
但是,当我从双引号中删除转义字符 \
并从整个对象周围删除双引号时,它可以很好地反序列化。
[
{"Location":"C:\\Users\\me\\Documents\\test.txt","Opacity":1.0}
]
在序列化或反序列化阶段是否应该应用任何配置以生成可以反序列化为 UserDataJson
列表的字符串?
假设您获取一个对象,并将其序列化为 JSON。你得到一个字符串,对吧?因此,如果您将该字符串添加到列表并序列化该列表,您会得到类似于上面的 JSON 的内容。
这是因为您的这部分序列化代码:.Select(Serialize)
。这一步似乎完全没有必要。
删除那个,我们得到这个:
public void SaveData(IReadOnlyCollection<IUserData> userData)
{
File.WriteAllText(_userDataFile, JsonConvert.SerializeObject(userData, Formatting.Indented));
}
private static string Serialize(IUserData userData) => JsonConvert.SerializeObject(new UserDataJson(userData));
现在这段代码应该可以反序列化结果 JSON:
var result = JsonConvert.DeserializeObject<List<UserDataJson>>(File.ReadAllText(_userDataFile));
我正在使用 Newtonsoft.JSON 序列化 List<UserDataJson>
,然后写入文件。这是 class:
private class UserDataJson
{
public UserDataJson() { }
public UserDataJson(string path)
{
Location = path;
Opacity = 1;
}
public UserDataJson(IUserData userData)
{
Location = userData.Location;
Opacity = userData.Opacity;
}
public string Location { get; set; }
public double Opacity { get; set; }
}
序列化写入的代码:
private static readonly string _userDataFile = Path.Combine(_programDataFolder, "userdata.json");
...
public void SaveData(IReadOnlyCollection<IUserData> userData)
{
File.WriteAllText(_userDataFile, JsonConvert.SerializeObject(userData.Select(Serialize).ToList(), Formatting.Indented));
}
private static string Serialize(IUserData userData) => JsonConvert.SerializeObject(new UserDataJson(userData));
对于一个元素,这会生成一个如下所示的 _userDataJson
文件:
[
"{\"Location\":\"C:\\Users\\me\\Documents\\test.txt\",\"Opacity\":1.0}"
]
然而,当我尝试反序列化时,我得到一个 JsonSerializationException
:
反序列化:
JsonConvert.DeserializeObject<List<UserDataJson>>(File.ReadAllText(_userDataFile).Replace("\\", "\");
异常:
{"Error converting value \"{\"Location\":\"C:\Users\me\Documents\test.txt\",\"Opacity\":1.0}\" to type 'Company.App.Wpf.MainWindow.UserDataService+UserDataJson'. Path '[0]', line 2, position 73."}
内部异常:
"Could not cast or convert from System.String to Company.App.Wpf.MainWindow.UserDataService+UserDataJson."
但是,当我从双引号中删除转义字符 \
并从整个对象周围删除双引号时,它可以很好地反序列化。
[
{"Location":"C:\\Users\\me\\Documents\\test.txt","Opacity":1.0}
]
在序列化或反序列化阶段是否应该应用任何配置以生成可以反序列化为 UserDataJson
列表的字符串?
假设您获取一个对象,并将其序列化为 JSON。你得到一个字符串,对吧?因此,如果您将该字符串添加到列表并序列化该列表,您会得到类似于上面的 JSON 的内容。
这是因为您的这部分序列化代码:.Select(Serialize)
。这一步似乎完全没有必要。
删除那个,我们得到这个:
public void SaveData(IReadOnlyCollection<IUserData> userData)
{
File.WriteAllText(_userDataFile, JsonConvert.SerializeObject(userData, Formatting.Indented));
}
private static string Serialize(IUserData userData) => JsonConvert.SerializeObject(new UserDataJson(userData));
现在这段代码应该可以反序列化结果 JSON:
var result = JsonConvert.DeserializeObject<List<UserDataJson>>(File.ReadAllText(_userDataFile));