C# 将Json反序列化到字典中<;字符串,对象>;使用BsonSerializer会导致FileFormatException

C# 将Json反序列化到字典中<;字符串,对象>;使用BsonSerializer会导致FileFormatException,c#,json,mongodb,C#,Json,Mongodb,我正在使用MongoDB返回一条记录,并且正确地返回了Json,我计划将Json转换为格式字典的字典,但每当我运行以下方法时,它都会返回一个空字典(由捕获异常引起) 传入的Json字符串是 "{ \"_id\" : ObjectId(\"4ed1062129d8145d74e9ab2f\"), \"1\" : \"New Guy\", \"2\" : \"26/11/2011\", \"4_25\" : \"Yes\", \"4_26\" : \"No\",

我正在使用MongoDB返回一条记录,并且正确地返回了Json,我计划将Json转换为格式字典的字典,但每当我运行以下方法时,它都会返回一个空字典(由捕获异常引起)

传入的Json字符串是

  "{ 
  \"_id\" : ObjectId(\"4ed1062129d8145d74e9ab2f\"), 
  \"1\" : \"New Guy\", 
  \"2\" : \"26/11/2011\", 
  \"4_25\" : \"Yes\", 
  \"4_26\" : \"No\", 
  \"5_25\" : \"No\", 
  \"5_26\" : \"Yes\", 
  \"6_25\" : \"Yes\", 
  \"6_26\" : \"No\", 
  \"7_25\" : \"\", 
  \"7_26\" : \"Comment in second box\", 
  \"19_21\" : { \"verified\" : true }, 
  \"10_19\" : \"0%\", 
  \"10_20\" : \"75% +\", 
  \"11_19\" : \"Diffuse\", 
  \"11_20\" : \"Localised\", 
  \"12_19\" : \"0-25%\", 
  \"12_20\" : \"50-75%\", 
  \"13_19\" : \"25-50%\", 
  \"13_20\" : \"25-50%\", 
  \"14_19\" : \"50-75%\", 
  \"14_20\" : \"0-25%\", 
  \"15_19\" : \"75% +\", 
  \"15_20\" : \"0%\", 
  \"17\" : \"Some comments at the bottom\" 
  }"
出什么事了?我怀疑这与键“19_21”上有一个对象有关,但这不应该导致它断裂,对吗

请注意,换行符只是为了使Json更易于阅读,并且不会传入。我也没有写这段代码,所以我不知道为什么这里使用BsonSerializer,当然也不知道是否有更好的选项可以使用

编辑:感谢回复的人,双重序列化是由于*19_21*中的值最初存储为文档中的Json字符串,现在它是文档中的文档,所以它的类型以前是字符串,所以这可以使用,人们正确地注意到,我只需要使用一次反序列化

 dict = (Dictionary<string, object>)BsonSerializer.Deserialize(json, typeof(Dictionary<string, object>);
dict=(字典)BsonSerializer;
谢谢你@L.B

但不幸的是,这仍然不能解决我的问题,如果对象是*19_21*中的字符串,它将起作用,但如果我在文档中使用新的文档格式,仍然会出现文件格式错误。有人知道我需要更改什么以使其正确工作吗?

使用,您可以按如下方式解析字符串

JObject jobj=  JObject.Parse(inputstr);

Console.WriteLine(jobj["_id"]);
Console.WriteLine(jobj["1"]);
Console.WriteLine(jobj["19_21"]["verified"]);
//OR
foreach (var kv in jobj)
{
    Console.WriteLine(kv.Key + ":" + kv.Value);
}

您的怀疑是正确的,它与嵌入的文档有关。问题是,即使您的字典将值存储为type object,反序列化程序也必须选择object的某个具体子类进行实际实例化,当它到达{verified:true}embedded document它无法确定应该反序列化到哪个数据类型(如果嵌入式文档为空,它将选择object,但当文档具有需要反序列化的值时,它无法选择object)

您可以反序列化到与字典非常相似的BsonDocument,只是值的类型是BsonValue而不是object。在这种情况下,嵌入的文档将只是BsonDocument的另一个实例


另一个响应也对反序列化的两次调用进行了评论。应该只需要一次调用。

仅供参考,我还遇到了此异常“FileFormatException:正在反序列化到系统的文档。对象必须为空”的问题当从数据库反序列化对象时,该对象有一个字典字段,其中包含一些复杂的Json文档

事实证明,BSON序列化程序需要知道要反序列化的对象的实际类型,否则它将尝试将其反序列化为System.object,但失败。实际类型名称应在json文档的_t字段中传递:

{ _t = "System.Collections.Generic.Dictionary`2[System.String,System.Object]" ...}

希望这将对某人有所帮助。

我正在寻找我的BsonSerializer实现的错误,如果我可以避免使用不同的Serializer,我会的,你知道我做错了什么吗?我没有使用MongoDB,我不知道它的类型,如
QueryDocument
。我也不理解这一点dict=(Dictionary)BsonSerializer.Deserialize(BsonSerializer.Deserialize(json),typeof(Dictionary));你试过这个例子吗,比如dict=(Dictionary)BsonSerializer.Deserialize(json,typeof(Dictionary);?
JObject jobj=  JObject.Parse(inputstr);

Console.WriteLine(jobj["_id"]);
Console.WriteLine(jobj["1"]);
Console.WriteLine(jobj["19_21"]["verified"]);
//OR
foreach (var kv in jobj)
{
    Console.WriteLine(kv.Key + ":" + kv.Value);
}
{ _t = "System.Collections.Generic.Dictionary`2[System.String,System.Object]" ...}