How to deserialize a BsonDocument object back to class How to deserialize a BsonDocument object back to class mongodb mongodb

How to deserialize a BsonDocument object back to class


There are three ways actually:

1.Specify type you want to load directly in FindAs<>

var docs = _collection.FindAs<MyType>(_document);

2.Deserialize document via BsonSerializer:

BsonSerializer.Deserialize<MyType>(doc);

3.Map bson document manually to your class:

var myClass = new Mytype();myClass.Name = bsonDoc["name"].AsString;

For most cases you are okay with first approach. But sometimes, when your documents is unstructured, you may need third approach.


For big applications and which has some structured data, it's recommended to use your custom model while creating and getting the data instead of using BsonDocument.

Creating a model is an important step for deserialization.

Helpful annotations to remember while creating your model:

  • add id property in model. Try to use [BsonId] attribute for good practice:
  • Create a property with annotation as [BsonExtraElements] this will be used to hold any extra elements found during deserialization.
  • you can use [BsonElement] to specify the elementName.
  • [BsonIgnoreIfDefault] - Initializes a new instance of the BsonIgnoreIfDefaultAttribute class

Sample Model structure, where I tried to cover maximum cases. I have created a base class for _id property just for better architecture, but you can use directly in MyModel class as well.

    public abstract class BaseEntity    {        // if you'd like to delegate another property to map onto _id then you can decorate it with the BsonIdAttribute, like this        [BsonId]        public string id { get; set; }    }    public class MyModel: BaseEntity    {        [BsonElement("PopulationAsOn")]        public DateTime? PopulationAsOn { get; set; }            [BsonRepresentation(BsonType.String)]        [BsonElement("CountryId")]        public int CountryId { get; set; }        [Required(AllowEmptyStrings = false)]        [StringLength(5)]        [BsonIgnoreIfDefault]        public virtual string CountryCode { get; set; }        [BsonIgnoreIfDefault]        public IList<States> States { get; set; }        [BsonExtraElements]        public BsonDocument ExtraElements { get; set; }    }

Now to Deserialise, directly use your model while calling FindAsync like this:

cursor = await _collection.FindAsync(filter, new FindOptions<MyModel, MyModel>() { BatchSize = 1000, Sort = sort }, ct);