C# JSON 将文件反序列化为对象列表失败,并将字符串转换为集合错误
Posted
技术标签:
【中文标题】C# JSON 将文件反序列化为对象列表失败,并将字符串转换为集合错误【英文标题】:C# JSON deserialize a file into object list fails with convert String to Collection error 【发布时间】:2021-11-08 21:21:14 【问题描述】:我有一个学校的小项目,我们在这里处理一些 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;
当然还有游戏类:
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));
我真的在互联网上四处寻找解决这个问题的方法,并尝试了其他几种方法。我无法发现问题。有没有其他人看到它并可以给我一个提示?
我在代码中所做的就像生成具有某些属性的游戏列表。一旦窗口关闭,我会将那个游戏对象列表推送到 json 中并保护它,一旦我们打开它就会重新加载。 所以它必须从json中获取对象列表。
提前非常感谢!
【问题讨论】:
var games = JsonConvert.DeserializeObject<List<Game>>(json);;
与发布的 Json 和 Game
类一起使用..
可能是转义双引号的问题。基于此链接:newtonsoft.com/json/help/html/readjsonwithjsontextreader.htm JsonTextReader 可能只接受带单引号的 json。尝试使用 @stuartd 建议的反序列化器。
大家好,Christoph 说的不对,我真的做了两次连载部分。一旦我将其更改为只执行一次序列化部分,一切正常,JSON 看起来也正确。感谢您的帮助!创建 JSON 而不是反序列化它是一个问题。
【参考方案1】:
并且此文件是有效的 JSON 格式
是的,它是有效的 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 字符串将产生一个如上所述的字符串。
解决方案:只编码一次。
【讨论】:
嗨,克里斯托夫,非常感谢!我在反序列化部分非常努力,以至于我没有仔细检查序列化部分。确实!我做了两次序列化部分。我头上的灰烬......但感谢您的快速帮助!大赞!现在它就像一个魅力。以上是关于C# JSON 将文件反序列化为对象列表失败,并将字符串转换为集合错误的主要内容,如果未能解决你的问题,请参考以下文章