MongoDb C# Deserialize interface throw exception

Hello everyone. I work with mongoDb Driver 2.18.0

I have objects two different classes that implement the same interface. I store these objects in a mongo DB which works fine. The problem is the deserialization of this objects when I filter on interface properties.

My data modeling

    // my interface
    public interface IAudit
    {      
        DateTime TimeStamp { get; set; }
        string IpAddress { get; set; }
    }
    
    // first implementation 
    public class AuditEdi : IAudit
    {
        public DateTime TimeStamp { get; set; }
        public string IpAddress { get; set; }
        public string MessageType { get; set; }
        ....
    }

    // second implementation 
    public class AuditIhm : IAudit
    {
        public Guid UserId { get; set; }
        public DateTime TimeStamp { get; set; }
        public string IpAddress { get; set; }
        ...
    }

Class Map registration

BsonClassMap.RegisterClassMap<AuditIhm>(cm =>
{
	cm.SetDiscriminator("AuditIhm");
	cm.AutoMap();
	cm.SetIgnoreExtraElements(true);
});

BsonClassMap.RegisterClassMap<AuditEdi>(cm =>
{
	cm.SetDiscriminator("AuditEdi");
	cm.AutoMap();
	cm.SetIgnoreExtraElements(true);
});

Try to filter on one of the interface’s property

    var filter = Builders<IAudit>.Filter.Eq(r => r.IpAddress, ipAddress);
    var sort = Builders<IAudit>.Sort.Descending("TimeStamp");
    var findOptions = new FindOptions<IAudit>() {Sort = sort};

the exception
System.InvalidOperationException : ‘Unable to determine the serialization information for r => r.IpAddress.’

Should i use class inheritance instead of interface for modeling my documents or is it possible to use this implementation ?

1 Like

Hi, @Yannick_Darcillon,

Welcome to the MongoDB Community Forums. I understand that you’ve encountered an unexpected serialization-related exception. When I ran your code (with some minor alterations to fill in the missing gaps), I did not encounter an exception.

using System;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;

BsonClassMap.RegisterClassMap<AuditIhm>(cm =>
{
    cm.SetDiscriminator("AuditIhm");
    cm.AutoMap();
    cm.SetIgnoreExtraElements(true);
});

BsonClassMap.RegisterClassMap<AuditEdi>(cm =>
{
    cm.SetDiscriminator("AuditEdi");
    cm.AutoMap();
    cm.SetIgnoreExtraElements(true);
});

var client = new MongoClient();
var db = client.GetDatabase("test");
var coll = db.GetCollection<ILifeCycleAudit>("coll");

var ipAddress = "127.0.0.1";
var filter = Builders<ILifeCycleAudit>.Filter.Eq(r => r.IpAddress, ipAddress);
var sort = Builders<ILifeCycleAudit>.Sort.Descending("TimeStamp");
var query = coll.Find(filter).Sort(sort);
Console.WriteLine(query);

// my interface
public interface ILifeCycleAudit
{
    DateTime TimeStamp { get; set; }
    string IpAddress { get; set; }
}

// first implementation
public class AuditEdi : ILifeCycleAudit
{
    public DateTime TimeStamp { get; set; }
    public string IpAddress { get; set; }
    public string MessageType { get; set; }
}

// second implementation
public class AuditIhm : ILifeCycleAudit
{
    public Guid UserId { get; set; }
    public DateTime TimeStamp { get; set; }
    public string IpAddress { get; set; }
}

The output of this code is:

find({ "IpAddress" : "127.0.0.1" }).sort({ "TimeStamp" : -1 })

Please provide a self-contained repro of the issue so that we can investigate further.

Sincerely,
James

I forgot the most important line of code in my example, the execution of the query ! If you add this the problem will appear :

coll.Find(filter).Sort(sort).ToEnumerable();

IEnumerable will not execute the query until you enumerate over the data.

best regard,
Yannick