Seb Krae
Seb Krae

Reputation: 311

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?

Upvotes: 2

Views: 5123

Answers (2)

mbinic
mbinic

Reputation: 31

Looking at the Setting the Discriminator Value section of MongoDB C# Driver documentation on polymorphism, it looks like annotating your classes with [BsonDiscriminator("EventData")] and [BsonDiscriminator("ExceptionData")], respectively, should be equivalent to the example from your answer.

Upvotes: 0

Seb Krae
Seb Krae

Reputation: 311

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.

Upvotes: 3

Related Questions