使用BsonSerializer将Json反序列化为Dictionary <string,object>会导致FileFormatException </string,object>

时间:2011-11-26 16:34:52

标签: c# json mongodb

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

 1.   public Dictionary<string, object> convertJsonToDict(string json)
 2.   { 
 3.       try
 4.       {
 5.           Dictionary<string, object> dict = new Dictionary<string,object>();
 6.           dict = (Dictionary<string, object>)BsonSerializer.Deserialize(BsonSerializer.Deserialize<QueryDocument>(json), typeof(Dictionary<string, object>));
 7.           return dict;
 8.       }
 9.       catch
10.        {
11.            return new  Dictionary<string, object>();
12.        }
13.    }

调试时,我在尝试反序列化Json时发现异常在第6行,错误是

FileFormatException: A document being deserialized to System.Object must be empty.

传入的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>);

谢谢@ L.B

遗憾的是,这仍然无法解决我的问题,如果对象是* 19_21 *中的字符串,它将起作用但如果我在文档中使用Document的新格式仍然会出现文件格式错误,是否有人有任何问题关于我需要改变什么以使其正常工作的想法?

3 个答案:

答案 0 :(得分:3)

您怀疑它与嵌入式文档有关是正确的。问题是即使你的Dictionary将值存储为类型对象,反序列化器也必须选择对象的一些具体子类来实际实例化,当它到达{verified:true}嵌入式文档时,它无法弄清楚是什么它应该反序列化的数据类型(如果嵌入文档是空的,它将选择对象,但是当文档具有需要反序列化的值时,它不能选择对象。)

您可以反序列化为BsonDocument,它与Dictionary类似,只是值为BsonValue而不是object。在这种情况下,嵌入的文档只是BsonDocument的另一个实例。

另一个回复也评论了反序列化的双重调用。应该只需要一个电话。

答案 1 :(得分:1)

使用Json.Net,您可以解析字符串,如下所示

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);
}

答案 2 :(得分:1)

仅供参考,我也遇到此异常的问题“FileFormatException:反序列化为System.Object的文档必须为空。”当从数据库反序列化一个对象时,该对象有一个Dictionary字段,里面有一些复杂的Json文档。

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

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

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