Search code examples
c#mongodbmongodb-.net-driver

Deserializing interface in MongoDB using C# - Unknown discriminator value


First of all, I use the current version of MongoDB (3.2) and its C#-driver (2.2.3). I have the following classes:

public class Item
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
    // ... some other properties

    public Data Data { get; set; }
}

public class Data
{
    public string BaseType { get; set; }
    public IBaseData BaseData { get; set; }
}

public interface IBaseData 
{
    string Name { get; set; }
    int Version { get; set; }
    IDictionary<string, object> PayloadData { get; }
}

Then I have some different implementations of the IBaseData interface:

public class EventData : IBaseData
{
    public int Version { get; set; }
    public string Name { get; set; }
    public IDictionary<string, object> PayloadData { get; set; }
    public IDictionary<string, object> Properties { get; set; }
}

public class ExceptionData : IBaseData
{
    // Implementation of the interface and some additional properties
}

Storing an Item-object to MongoDB is no problem and it seems that everything is correct. Mongo uses the _t to determine the type of IBaseData (e.g. EventData). When I try to retrieve the data for the first time, it works perfectly which means I have the complete tree of objects. When I restart the application and post the same request again, I get the following error:

An error occurred while deserializing the Data property of class Domain.Objects.Item: An error occurred while deserializing the BaseData property of class Domain.Objects.Data: Unknown discriminator value 'EventData'.

After dropping the Mongo-database and starting the application, it works again as expected.

Google gave me different approaches but nothing helped me:

Storing a Dictionary with polymorphic values in mongoDB using C#

Unknown discriminator value 'MyEvent'

Deserialize object as an interface with MongoDB C# Driver

I would like to work with property annotations like [BsonKnownTypes(typeof(Type1), typeof(Type2)], but this just works for classes.

Do you have an idea?


Solution

  • I partially solved the problem for me by adding a classmap in Program.cs (or other application-start class):

            BsonClassMap.RegisterClassMap<EventData>(cm =>
            {
                cm.AutoMap();
                cm.SetDiscriminator("EventData");
            });
    
            BsonClassMap.RegisterClassMap<ExceptionData>(cm =>
            {
                cm.AutoMap();
                cm.SetDiscriminator("ExceptionData");
            });
    

    If somebody find a way to work with annotations, please answer to this question.