#c# #json #json.net
Вопрос:
Я сериализуюа с 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."
Однако, когда я удаляю escape-символ
из двойных кавычек и удаляю двойные кавычки вокруг объекта в целом, тогда он десериализуется нормально.
[
{"Location":"C:\\Users\\me\\Documents\\test.txt","Opacity":1.0}
]
Есть ли какая-либо конфигурация, которую я должен применять на этапе сериализации или десериализации, чтобы создать строку, которую можно десериализовать в список UserDataJson
?
Комментарии:
1. Это не объект, это обычная старая строка. В коде, который вызвал это, есть ошибка, а не в JSON.NET . Что-то, заключенное в двойные кавычки в JSON, является строкой, независимо от того, что она содержит
2. Представьте, что вы берете объект и сериализуете его как JSON. Вы получаете строку, верно? Поэтому, если вы добавите эту строку в список и сериализуете список, вы получите что-то вроде вашего JSON выше. Это связано с этой частью вашего
Serialize
кода :.Select(Serialize)
. Этот шаг вообще не кажется необходимым.3. Спасибо @Llama, вы правы. Если вы ответите на вопрос таким образом, я соглашусь.
Ответ №1:
Представьте, что вы берете объект и сериализуете его как 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));
Комментарии:
1. Просто в качестве примечания мне пришлось изменить
IReadOnlyCollection<IUserData>
IReadOnlyList<IUserData>
на, чтобы перейтиuserData
непосредственно вSerializeObject
.