反序列化Bson文件

5
我有一个使用mongodump工具生成的Bson文件,我想在C#代码中对其进行反序列化。为此,似乎可以使用mongodb C#驱动程序或Json.net库。我尝试了它们两个,但无法使它们正常工作。
使用Json.net库: “input”是Bson文件的路径。
JsonSerializer serializer = new JsonSerializer();
BsonReader reader = new BsonReader(File.OpenRead(input));
serializer.Deserialize<List<Json.Profil>>(reader);

在执行Deserialize()时,我遇到了以下异常:
无法将当前JSON对象(例如{"name":“value”})反序列化为类型“System.Collections.Generic.List`1[MoulinetteConsole.Json.Profil]”,因为该类型需要一个JSON数组(例如[1,2,3])才能正确反序列化。
要解决此错误,请将JSON更改为JSON数组(例如[1,2,3]),或更改反序列化类型,使其成为普通的.NET类型(例如,不是整数这样的基元类型,不是像数组或List这样的集合类型),可以从JSON对象反序列化。还可以向类型添加JsonObjectAttribute以强制它从JSON对象反序列化。
如果使用bsondump工具将bson导出为json文件,则会得到以下结果: [EDIT]
{ "id" : "1",
  "value" : { "foo" : null, "bar" : "test"}
}
{ "id" : "2",
  "value" : { "foo" : null, "bar" : "test"}
}

此外,如果我替换:
serializer.Deserialize<List<Json.Profil>>(reader);

by

serializer.Deserialize<Json.Profil>(reader);

我不再收到异常,但我只能检索集合中的第一条记录。


读取bson文件并获取不止第一个元素有成功的吗?我手头也有同样的问题,无论我使用什么方法(Newtonsoft、MongoDB,甚至是在线bson => json转换器),都只能获取到第一个元素。 - Aaginor
已经有一段时间了,但我记得最终通过一个解决方法解决了我的问题:如果您可以修改JSON文件,请将集合放置在根元素下。这样,在反序列化文件时,您将获得根元素,即第一个元素。然后,您只需要探索其子元素即可。希望这可以帮助到您。 - Mjollnir
嘿Mjollnir,谢谢你的回复!不幸的是,我只有一个bson文件作为MongoDB的转储,并且想要获取数据。需要找到另一种解决方法... - Aaginor
3个回答

3

最终找到答案。假设您正在反序列化动物,并且您的C#代码中有一个类Animal,该类正确地映射到您正在反序列化的内容。在这种情况下,此代码将起作用:

运行此命令以确保您拥有bson文件:

mongodump --db=MyDatabase --collection=Animals --out=/tmp/output 

然后将生成的bson文件导入:

var path = "/tmp/output/MyDatabase/Animals.bson";

using var fileStream = File.OpenRead(path);
FileInfo fi = new FileInfo(path);
var size = fi.Length;
while (fileStream.Position<size)
{
    var animal = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<Animal>(fileStream);
    Console.WriteLine(animal.Name);
}

0

你的文件可能包含类似于这样的Json

{
    "foo":1,
    "bar":"baz"
}

但是尝试反序列化为List<>时,反序列化程序会期望

[{
    "foo":1,
    "bar":"baz"
},
{
    "foo":2,
    "bar":"baz"
},
...]

只需将反序列化行更改为:

serializer.Deserialize<Json.Profil>(reader);

应该可以工作。

这就是错误提示:

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“System.Collections.Generic.List`1[MoulinetteConsole.Json.Profil]”,因为该类型需要一个 JSON 数组(例如 [1,2,3])才能正确反序列化。

要解决此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3]),或者更改反序列化类型,使其成为普通的 .NET 类型(例如不是像整数这样的基元类型,也不是像数组或 List 这样的集合类型)可以从 JSON 对象反序列化。还可以向类型添加 JsonObjectAttribute,以强制它从 JSON 对象反序列化。


我忘了说:该文件包含一组配置文件。当我使用 bsondump 查看其中内容时,我看到 { "foo": 1}{"foo":2},等等。但是没有根元素。 - Mjollnir
@user3635728 请在你的问题中发布一个你正在反序列化的JSON样本。 - dav_i
好的,我会尽快完成。请注意,有了您的提示,我成功地检索到了列表的第一个元素。 - Mjollnir
@user3635728 如果你的JSON看起来像这样{"foo":1}{"bar":2},那么它似乎是无效的。如果你有多个项目,它应该像这样[{"foo":1},{"bar":2}] - dav_i
我同意你的观点,问题是我无法控制输入文件的生成方式。我猜我可以通过编程的方式添加方括号... - Mjollnir
如果你想要反序列化,就需要这样做。不要忘记逗号! - dav_i

0

尝试设置 BSON Reader 的属性 -- ReadRootValueAsArray = true


谢谢,但我尝试过这个方法,只能读取第一个元素。 - Mjollnir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接