Rodrigo Campos-Cervera Rodrigo Campos-Cervera -4 years ago 87
ASP.NET (C#) Question

Mapping BsonDocument to class but getting error

This is my BsonDocument that I extract from my MongoDb collection. I would like to deserialize (or map) this to an object/class that I made in C#.

{
"_id" : ObjectId("5699715218a323101c663b9a"),
"type": null,
"text": "Hello this is text",
"user":
{
"hair": "brown",
"age": 64
}
}


This is the class that I would like to map/deserialize the BsonDocument to. The fields inside my class are the only ones that I would like to retrieve.

public class MyType
{
public BsonObjectId _id { get; set; }
public BsonString text { get; set; }
}


Currently this is how I am trying to do this but I am getting an error that "Element 'type' does not match any field or property of class MyType". I do not want to include "type" field in the MyType class.

var collection = db.GetCollection<BsonDocument>("data_of_interest");
var filter = new BsonDocument();
var myData = collection.Find(filter).FirstOrDefault();
MyType myObject = BsonSerializer.Deserialize<MyType>(myData);


I'm getting the error on the last line. In this example I am trying to do this for just one document to one instance of the MyType object. I am also interested in how to deserialize a whole collection to a list of the MyType object or something similar where it isn't for just one BsonDocument but for all of the documents in my collection.

Thanks for your time.

Answer Source

BsonIgnoreExtraElements

Flag your class with the [BsonIgnoreExtraElements] attribute. That will tell the c# driver not to freak out if there isn't a 1:1 match between your class properties and the mongo record.

[BsonIgnoreExtraElements]
public class MyType
{
    public BsonObjectId _id { get; set; }
    public BsonString text { get; set; }
}

With this approach, the type and user properties are going to be ignored.

Add a "catch all" property for extra elements

If you'd rather not ignore those elements, then you could add a catch all property that will house all your extra "undeclared" properties in a bson document.

public class MyType
{
    public BsonObjectId _id { get; set; }
    public BsonString text { get; set; }
    [BsonExtraElements]
    public BsonDocument CatchAll { get; set; }
}

With this approach, type and user will exist as properties of the .CatchAll property.

What's the Advantage?

One big advantage is that you can do a "findAndReplace" with the latter without losing the data from fields you aren't mapping.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download