C# JSON 将文件反序列化为对象列表失败,并出现将字符串转换为集合错误
C# JSON deserialize a file into object list fails with convert String to Collection error
我有一个学校的小项目,我们正在处理这里的一些 json 事情。
我可以将对象列表写入 JSON 并且此文件是有效的 JSON 格式。
没有,一旦我加载了完全相同的文件,我确实收到了一个错误,抱怨无法转换。这是消息:
Newtonsoft.Json.JsonSerializationException
HResult=0x80131500
Message=Error converting value "[
{
"ID": 500455154,
"Title": "GameOne",
"MinAge": 14,
"Price": 12.8,
"State": "New",
"Players": 4
},
{
"ID": 860100321,
"Title": "Gametwo",
"MinAge": 14,
"Price": 12.8,
"State": "New",
"Players": 4
},
{
"ID": 358239485,
"Title": "Gamethree",
"MinAge": 14,
"Price": 12.8,
"State": "New",
"Players": 4
}
]" to type 'System.Collections.Generic.List`1[Ludothek.Game]'. Path '', line 1, position 513.
Source=Newtonsoft.Json
StackTrace:
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Ludothek.DATA.loadData_Games() in epos\Ludothek\Ludothek\DATA.cs:line 71
at Ludothek.Program.Main(String[] args) in \r\Program.cs:line 16
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List`1[Ludothek.Game].
这是我加载此文件并将其推送到现有游戏列表的函数:
public List<Game> loadData_Games()
{
var Gl = new List<Game>();
string[] files = Directory.GetFiles(folder, "games.json");
foreach (var file in files)
using (StreamReader sr = new StreamReader(file))
{
using (JsonReader jsr = new JsonTextReader(sr)) {
var Serializer = new JsonSerializer();
Gl = (List<Game>)Serializer.Deserialize(jsr, typeof(List<Game>));
// above is where it hits the fan...
}
}
return Gl;
}
当然还有游戏class:
public class Game : AbstGame
{
[JsonProperty("ID")]
public override int ID { get ; }
[JsonProperty("Title")]
public override string Title { get ; set ; }
[JsonProperty("MinAge")]
public override int MinAge { get ; set ; }
[JsonProperty("Price")]
public override double Price { get; set ; }
[JsonProperty("State")]
public override string State { get; set ; }
[JsonProperty("Players")]
public int Players { get; set; }
public Game(string title, int minAge, double price,string state, int players)
{
Random rnd = new Random();
ID = rnd.Next(1, 999999999);
Title = title;
MinAge = minAge;
Price = price;
State = state;
Players = players;
}
我是这样写的:
public void backUp_Games(List<Game> games)
{
string filename = "games";
string jsonGames = JsonConvert.SerializeObject(games,Formatting.Indented);
backUp(filename, jsonGames);
}
public void backUp(string fileName ,string json)
{
string filename = @"C:\.....\Desktop\JsonTest\"+fileName+".json"; // not the actual path ;)
File.WriteAllText(filename, JsonConvert.SerializeObject(json,Formatting.Indented));
}
我真的在互联网上寻找解决这个问题的方法,并且已经尝试了其他几种方法。我无法发现问题。还有其他人看到它并可以给我提示吗?
我在代码中所做的就像生成具有某些属性的游戏列表。 window 关闭后,我会将游戏对象列表推入 json 并保护它,一旦我们打开它,它就会重新加载。
所以它必须从 json.
中获取对象列表
非常感谢!
and this file is a valid JSON format
是的,它是有效的 JSON,但不是您所期望的。你写了一个只有一个 JSON 字符串的文件。
简化示例:
"foo"
这是有效的json。它只是一个字符串。你做同样的事情,但字符串内容看起来像 JSON.
"{\"foo\": \"bar\"}"
这仍然只是一个没有 JSON 对象的字符串。
这就是您收到错误的原因:无法从 System.String 转换或转换为 System.Collections.Generic.List`1[Ludothek.Game].
这就是你要做的...
string jsonGames = JsonConvert.SerializeObject(games,Formatting.Indented);
// string jsonGames is the JSON you want but then you do...
File.WriteAllText(filename, JsonConvert.SerializeObject(json,Formatting.Indented));
因此,您执行 JSON 编码两次,JSON 编码 JSON 字符串将产生如上所述的字符串。
解决方案:只编码一次。
我有一个学校的小项目,我们正在处理这里的一些 json 事情。 我可以将对象列表写入 JSON 并且此文件是有效的 JSON 格式。 没有,一旦我加载了完全相同的文件,我确实收到了一个错误,抱怨无法转换。这是消息:
Newtonsoft.Json.JsonSerializationException
HResult=0x80131500
Message=Error converting value "[
{
"ID": 500455154,
"Title": "GameOne",
"MinAge": 14,
"Price": 12.8,
"State": "New",
"Players": 4
},
{
"ID": 860100321,
"Title": "Gametwo",
"MinAge": 14,
"Price": 12.8,
"State": "New",
"Players": 4
},
{
"ID": 358239485,
"Title": "Gamethree",
"MinAge": 14,
"Price": 12.8,
"State": "New",
"Players": 4
}
]" to type 'System.Collections.Generic.List`1[Ludothek.Game]'. Path '', line 1, position 513.
Source=Newtonsoft.Json
StackTrace:
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Ludothek.DATA.loadData_Games() in epos\Ludothek\Ludothek\DATA.cs:line 71
at Ludothek.Program.Main(String[] args) in \r\Program.cs:line 16
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List`1[Ludothek.Game].
这是我加载此文件并将其推送到现有游戏列表的函数:
public List<Game> loadData_Games()
{
var Gl = new List<Game>();
string[] files = Directory.GetFiles(folder, "games.json");
foreach (var file in files)
using (StreamReader sr = new StreamReader(file))
{
using (JsonReader jsr = new JsonTextReader(sr)) {
var Serializer = new JsonSerializer();
Gl = (List<Game>)Serializer.Deserialize(jsr, typeof(List<Game>));
// above is where it hits the fan...
}
}
return Gl;
}
当然还有游戏class:
public class Game : AbstGame
{
[JsonProperty("ID")]
public override int ID { get ; }
[JsonProperty("Title")]
public override string Title { get ; set ; }
[JsonProperty("MinAge")]
public override int MinAge { get ; set ; }
[JsonProperty("Price")]
public override double Price { get; set ; }
[JsonProperty("State")]
public override string State { get; set ; }
[JsonProperty("Players")]
public int Players { get; set; }
public Game(string title, int minAge, double price,string state, int players)
{
Random rnd = new Random();
ID = rnd.Next(1, 999999999);
Title = title;
MinAge = minAge;
Price = price;
State = state;
Players = players;
}
我是这样写的:
public void backUp_Games(List<Game> games)
{
string filename = "games";
string jsonGames = JsonConvert.SerializeObject(games,Formatting.Indented);
backUp(filename, jsonGames);
}
public void backUp(string fileName ,string json)
{
string filename = @"C:\.....\Desktop\JsonTest\"+fileName+".json"; // not the actual path ;)
File.WriteAllText(filename, JsonConvert.SerializeObject(json,Formatting.Indented));
}
我真的在互联网上寻找解决这个问题的方法,并且已经尝试了其他几种方法。我无法发现问题。还有其他人看到它并可以给我提示吗?
我在代码中所做的就像生成具有某些属性的游戏列表。 window 关闭后,我会将游戏对象列表推入 json 并保护它,一旦我们打开它,它就会重新加载。 所以它必须从 json.
中获取对象列表非常感谢!
and this file is a valid JSON format
是的,它是有效的 JSON,但不是您所期望的。你写了一个只有一个 JSON 字符串的文件。
简化示例:
"foo"
这是有效的json。它只是一个字符串。你做同样的事情,但字符串内容看起来像 JSON.
"{\"foo\": \"bar\"}"
这仍然只是一个没有 JSON 对象的字符串。
这就是您收到错误的原因:无法从 System.String 转换或转换为 System.Collections.Generic.List`1[Ludothek.Game].
这就是你要做的...
string jsonGames = JsonConvert.SerializeObject(games,Formatting.Indented);
// string jsonGames is the JSON you want but then you do...
File.WriteAllText(filename, JsonConvert.SerializeObject(json,Formatting.Indented));
因此,您执行 JSON 编码两次,JSON 编码 JSON 字符串将产生如上所述的字符串。
解决方案:只编码一次。