Home > OS >  Newtonsoft.JSON chokes on deserializing object that's surrounded by double quotes in an array
Newtonsoft.JSON chokes on deserializing object that's surrounded by double quotes in an array

Time:11-01

I am serializing a List<UserDataJson> using Newtonsoft.JSON and then writing to a file. Here is the 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; }
}

The code that serializes and writes:

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));

With one element, this produces a _userDataJson file that looks like the following:

[
  "{\"Location\":\"C:\\\\Users\\\\me\\\\Documents\\\\test.txt\",\"Opacity\":1.0}"
]

However, when I try to deserialize I get a JsonSerializationException:

Deserialization:

JsonConvert.DeserializeObject<List<UserDataJson>>(File.ReadAllText(_userDataFile).Replace("\\\\", "\\");

Exception:

{"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."}

Inner Exception:

"Could not cast or convert from System.String to Company.App.Wpf.MainWindow.UserDataService UserDataJson."

However, when I remove the escape-character \ from the double quotes and remove the double quotes from around the object as a whole, then it deserializes fine.

[
  {"Location":"C:\\\\Users\\\\me\\\\Documents\\\\test.txt","Opacity":1.0}
]

Is there any configuration that I should be applying during the serialization or deserialization stage in order to produce a string that can be deserialized into a list of UserDataJson?

CodePudding user response:

Imagine you take an object, and serialize it as JSON. You get a string, right? So if you add that string to a list and serialize the list, you get something like your JSON above.

This is because of this part of your Serialize code: .Select(Serialize). This step doesn't seem necessary at all.

Removing that, we get this:

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));

And this code should now work to deserialize the resultant JSON:

var result = JsonConvert.DeserializeObject<List<UserDataJson>>(File.ReadAllText(_userDataFile));

Try it online

  • Related