BsonSerializer.Deserialize <t>(bsonDocument) - 子对象的Id字段导致异常

时间:2017-06-01 12:58:29

标签: c# mongodb deserialization mongodb-.net-driver bson

我有一个A类,一个B和C

public class A  
{ 
    public string Id {get;set;}
    public List<B> Children {get;set;}
}
public class B
{
    public string Id {get;set;}
    public string Foo {get;set;}
    public double Bar {get;set;}
}
public class C 
{
    public string Id {get;set;}
    //This property will hold a serialized version of Class A.
    //The scenario requirement is that it can hold any arbitrary BsonDocument of different types
    public BsonDocument Properties {get;set;} 
}

var instanceOfClassC = collection.Find(...).First();

var data = BsonSerializer.Deserialize<A>(instanceOfClassC.Properties);

这最后一行导致例外。 如果我将忽略BsonElement添加到B类的Id属性,它可以正常工作。 但我需要Id属性!

例外:

  

未处理的类型&#39; System.FormatException&#39;发生在MongoDB.Bson.dll

     

其他信息:反序列化NameSpace.A类的Children属性时发生错误:元素&#39; Id&#39;与NameSpace.B类的任何字段或属性都不匹配。

     

未处理的类型&#39; System.FormatException&#39;发生在MongoDB.Bson.dll

问题似乎是属性B.Id实际上存储为&#34; Id&#34;在MongoDb,因为它&#34;序列化&#34;存储前到BsonDocument。否则相同的模式总是完美的,但是MongoDb将转换为Id =&gt;在写作时_id。

要求:类C.Properties包含任意种类的其他有效类类型,并且不能在类声明中更改为类型A.它工作顺利 - 除了嵌套的Id属性!

更新:找到了一个残酷的黑客解决方案:重命名所有&#34; Id&#34; BsonDocument中的属性为&#34; _id&#34;在运送到MongoDb之前。然后反序列化按预期工作。我用字符串替换json来做到这一点 json.Replace(&#34; \&#34; Id \&#34;&#34;,&#34; \&#34; _id \&#34;&#34;)

任何人都有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

更清洁的解决方案是:

public class A  
{ 
    public string Id {get;set;}
    public List<B> Children {get;set;}
}
[BsonNoId] // this solves the problem
public class B
{
    public string Id {get;set;}
    public string Foo {get;set;}
    public double Bar {get;set;}
}

您也可以使用BsonClassMap:

在没有属性的情况下执行此操作
BsonClassMap.RegisterClassMap<B>(cm =>
{
    cm.SetIdMember(null);
});

如果要映射的类型来自不同的库

,那么这是有用的