1

I'm using MongoDB Driver to try and map BsonDocument to a model. When I try to read models from a collection, string values are null, DateTimes are the minimum value, and enums are their default value. Here is a document I'd like to read from a collection:

enter image description here

This is the class I'd like to map it to:

public class PhotoModel
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
    public string Name { get; set; }
    [BsonSerializer(typeof(PhotoCategorySerializer))]
    public PhotoCategory Category { get; set; }
    public string Description { get; set; }
    public string UserID { get; set; }
    public DateTime Created { get; set; }
}

Here is where I define the mapping:

BsonClassMap.RegisterClassMap<PhotoModel>(cm =>
        {
            cm.MapMember(c => c.Id);
            cm.MapMember(c => c.Name);
            cm.MapMember(c => c.Description);
            cm.MapMember(c => c.Category);
            cm.MapMember(c => c.UserID);
            cm.MapMember(c => c.Created);
        });

I use MapMember instead of AutoMap because I don't want file to be a part of my model. This is the code where I try to read from the collection:

public class PhotoRepository : IPhotoRepository
{
    private readonly IMongoCollection<PhotoModel> photos;

    public PhotoRepository(IMongoClient mongoClient)
    {
        photos = mongoClient.GetDatabase("photo-share").GetCollection<PhotoModel>("photos");
    }

    public IEnumerable<PhotoModel> GetAllPhotos() => photos.Find(new BsonDocument()).ToList();
}

This is what I see when I debug photos.Find(new BsonDocument()).ToList(): enter image description here

Why is the class not mapped properly?

Also, a related question: where should I perform the mappings? The docs said to register class maps before initializing a MongoDB connection, so I do it in Program.cs before the host is built and run. Is that a good place for it?

1
  • Maybe, the the field names of MongoDB collection document and the class property names need to be of the same case (right now it is name and Name respectively). Commented Aug 20, 2021 at 3:25

1 Answer 1

1

do it like this. you don't even need to specify mapping. mongo driver takes care of that. your main problem is the mismatched casing of db field names and class property names.

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace StackOverflow
{
    [BsonIgnoreExtraElements]
    public class PhotoModel
    {
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

        [BsonElement("name")]
        public string Name { get; set; }

        [BsonElement("category"), BsonSerializer(typeof(PhotoCategorySerializer))]
        public PhotoCategory Category { get; set; }

        [BsonElement("description")]
        public string Description { get; set; }

        [BsonElement("userID")]
        public string UserID { get; set; }

        [BsonElement("created")]
        public DateTime Created { get; set; }
    }

    internal static class Program
    {
        private static readonly IMongoClient client = 
            new MongoClient("mongodb://localhost");

        private static readonly IMongoCollection<PhotoModel> photoCollection =
            client.GetDatabase("photo-share").GetCollection<PhotoModel>("photos");

        private static async Task Main()
        {
            IEnumerable<PhotoModel> photos = await photoCollection.Find(_ => true).ToListAsync();
        }
    }
}

you could even eliminate the need for the attribute decorations by registering a convension pack like so:

ConventionRegistry.Register(
    "MyConvensions",
    new ConventionPack
    {
        new IgnoreExtraElementsConvention(true),
        new CamelCaseElementNameConvention()
    },
    _ => true);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. It worked! I have a question about the convention pack though. Where should this registration be performed? I'm guessing Program.cs or Startup.cs.
@AnthonyBias starup.cs should be ok. basically anywhere before the mongo client is created i believe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.