首页 > 解决方案 > Newtonsoft.JSON 在反序列化数组中被双引号包围的对象时窒息

问题描述

我正在List<UserDataJson>使用 Newtonsoft.JSON 序列化一个然后写入文件。这是课程:

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吗?

标签: c#jsonjson.net

解决方案


假设您获取一个对象,并将其序列化为 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));

在线尝试


推荐阅读