我无法反序列化包含多个Account
类型对象的JSON文件。以下是我构建data.json
文件的方法。我有一个帐户列表List<Account>
,它像往常一样序列化。我通过添加一个新行来分隔json文件中的每个对象。
List<Account> listOfAccounts = new List<Account>();
if (listOfAccounts != null)
{
foreach (var item in listOfAccounts)
{
JavaScriptSerializer ser = new JavaScriptSerializer();
string outputJSON = ser.Serialize(item);
// I added Environmetn.NewLine to separate each account in json file.
File.AppendAllText("data.json", outputJSON + Environment.NewLine);
}
}
现在,当我尝试将所有帐户从JSON文件检索到List<Account>
时,我收到错误消息:System.ArgumentException: 'Invalid JSON primitive:
请帮助找到solutin,这样我就可以从JSON文件中获取所有对象。
private void JsonFileLoad()
{
if(File.Exists("data.json"))
{
String JSONtxt = File.ReadAllText("data.json");
JavaScriptSerializer ser = new JavaScriptSerializer();
// Not sure how to deserialize all lines into List<account>
List<Account> desirializedAccounts = ser.Deserialize<List<Account>>(JSONtxt);
}
}
我非常感谢您提供的任何帮助。
答案 0 :(得分:2)
首先,您应该使用标准的json格式进行序列化。你正在做的是序列化对象和写入文件。应该是,将列表完全序列化为json格式。 但假设您可能有特定的原因,我在不同的场景中给出了许多可能的解决方案。
注意:我使用了Newtonsoft.Json,因为这很快,我觉得很容易。 http://www.newtonsoft.com/json
https://www.nuget.org/packages/newtonsoft.json/
解决方案:
//Class for testing object
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
}
解决方案1:推荐
/// <summary>
/// Serializing the list in single go
/// </summary>
public void Serialize()
{
List<Account> listOfAccounts = new List<Account>();
listOfAccounts.Add(new Account { Id = 1, Name = "First" });
listOfAccounts.Add(new Account { Id = 2, Name = "Second" });
listOfAccounts.Add(new Account { Id = 3, Name = "Third" });
string outputJSON = Newtonsoft.Json.JsonConvert.SerializeObject(listOfAccounts, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(@"c:\temp\data.json", outputJSON + Environment.NewLine);
}
/// <summary>
/// Serializing the list, one by one object
/// Comma is appended to every object in json format
/// Finally, enclosed it with [ and ] to make it array of objects
/// </summary>
public void Serialize2()
{
List<Account> listOfAccounts = new List<Account>();
listOfAccounts.Add(new Account { Id = 1, Name = "First" });
listOfAccounts.Add(new Account { Id = 2, Name = "Second" });
listOfAccounts.Add(new Account { Id = 3, Name = "Third" });
string outputJSON = "";
foreach(var item in listOfAccounts)
{
outputJSON += Newtonsoft.Json.JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented)+",";
}
File.WriteAllText(@"c:\temp\data.json", "["+outputJSON + "]");
}
/// <summary>
/// Read serialized data into list of objects
/// </summary>
public void DeSerialize()
{
if (File.Exists(@"c:\temp\data.json"))
{
String JSONtxt = File.ReadAllText(@"c:\temp\data.json");
var accounts = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Account>>(JSONtxt);
}
}
解决方案2:根据您的要求
/// <summary>
/// Non standard json serialization (object one by one) Highly discouraged unless you have specific reason
/// Assuming the output will not have internal objects
/// </summary>
public void SerializeNonStandard()
{
List<Account> listOfAccounts = new List<Account>();
listOfAccounts.Add(new Account { Id = 1, Name = "First" });
listOfAccounts.Add(new Account { Id = 2, Name = "Second" });
listOfAccounts.Add(new Account { Id = 3, Name = "Third" });
foreach (var item in listOfAccounts)
{
string outputJSON = Newtonsoft.Json.JsonConvert.SerializeObject(item, Newtonsoft.Json.Formatting.Indented);
File.AppendAllText(@"c:\temp\data-ns.json", outputJSON + Environment.NewLine);
}
}
/// <summary>
/// Deserializes the list in one by one fashion and appends to list
/// </summary>
public void DeSerializeNonStandard()
{
if (File.Exists(@"c:\temp\data-ns.json"))
{
List<Account> listOfAccounts = new List<Account>();
String JSONtxt = File.ReadAllText(@"c:\temp\data-ns.json");
//Capture JSON string for each object, including curly brackets
Regex regex = new Regex(@".*(?<=\{)[^}]*(?=\}).*", RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(JSONtxt);
foreach(Match match in matches)
{
string objStr = match.ToString();
Account account = Newtonsoft.Json.JsonConvert.DeserializeObject<Account>(objStr);
listOfAccounts.Add(account);
}
}
}
/// <summary>
/// Deserializes the non standard json to list of accounts
/// Splits the object strings, merges with comma and encloses with [] to make it array of objects format and deserializes
/// </summary>
public void DeSerializeNonStandardList()
{
if (File.Exists(@"c:\temp\data-ns.json"))
{
String JSONtxt = File.ReadAllText(@"c:\temp\data-ns.json");
//Capture JSON string for each object, including curly brackets
Regex regex = new Regex(@".*(?<=\{)[^}]*(?=\}).*", RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(JSONtxt);
string joinedJSON = string.Join(",", matches.Cast<Match>().Select(m => m.Value));
joinedJSON = string.Format("[{0}]", joinedJSON);
var listOfAccounts = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Account>>(joinedJSON);
}
}
答案 1 :(得分:1)
您正在序列化帐户而不是帐户列表,这就是为什么反序列化失败的原因。你需要在新的行中分开这些帐户吗?如果是这样你可以尝试添加char&#39; [&#39;在第一个和最后一个char&#39;]&#39;在data.json。