Search code examples
c#mongodbserializationmongodb-.net-driver

How to write custom serializer for entity with MobogDB C# Driver?


I'm trying to get a document from database, but I can't do it in a desirable way. It seems handy to use this approach to retrieve data:

var filter = Builders<Book>.Filter.Eq(x => x.Id == new ObjectId(id), true);
var result = await coll.Find(filter).ToListAsync();

But in this case InvalidOperationException is thrown when executing Find method. Exception text: Unable to determine the serialization information for x => (x.Id == new ObjectId(value(BookService.Controllers.ImportController+<>c__DisplayClass1_0).id)).

public class Book
{
    [BsonId]
    public ObjectId Id { get; set; }

    public string Author { get; set; }

    public string Title { get; set; }
}

Otherwise, when I use this filter:

var filter = Builders<Book>.Filter.Eq("_id", new ObjectId(id));

there are no any exceptions and result contains proper entity instances. It seems that I need to implement custom serializer to determine that when x.Id is used it means to search by _id field, but I don't know how to do that. Or maybe there are some other ways to make this work?


Solution

  • This code is incorrect:

    var filter = Builders<Book>.Filter.Eq(x => x.Id == new ObjectId(id), true);
    

    Change it to this and it should fix your problem

    var filter = Builders<Book>.Filter.Eq(x => x.Id, new ObjectId(id));
    

    I always represent ObjectId as string in my C# models and use BsonRepresentation as an attribute to ensure correct serialization

    [BsonRepresentation(BsonType.ObjectId)]
    [BsonId]
    public string Id { get; set; }
    

    That way your queries just look like this:

    var filter = Builders<Book>.Filter.Eq("_id", id);
    var result = await coll.Find(filter).ToListAsync();
    

    Or even better

    var result = await coll.Find(x => x.Id == id).ToListAsync();