bombek
bombek

Reputation: 584

MongoDB deserialization in C# when custom id field

I've got following structure in the database:

{
      "_id" : ObjectId(""),
      "title" : "something",
      "id" : 1,
      (...)
}

Basicly i want to retrive data from following collection to my Class:

[BsonIgnoreExtraElements]
public class Topic
{
    [BsonElement("id")]
    public int Id { get; set; }
    [BsonElement("title")]
    public string Name { get; set; }
}

The problem is this code doesn't work -> executes with error message: Cannot deserialize a 'Int32' from BsonType 'ObjectId', but this one does:

[BsonIgnoreExtraElements]
public class Topic
{
    [BsonIgnore]
    public int Id { get; set; }
    [BsonElement("title")]
    public string Name { get; set; }
    [BsonElement("id")]
    public int IdTest { get; set; }

Seems like deserialization desperatly tries to match class property with name "Id" with the ObjectId in database which is not correct because i explicitly declare that i want to match it with BsonElement("id") and not ("_id").

I appreciate any ideas how to make it works as I need to.

Upvotes: 5

Views: 6852

Answers (2)

mohamed.dhifi
mohamed.dhifi

Reputation: 61

Your "_id" stored in your mongo document is of type BsonType.ObjectId so when deserializing, the Serializer try to find a property with the name "Id" and with type of ObjectId. In your case it found matched name but not the right type which is int (int32 type in your class): my suggestion is to change

public int Id { get; set; }

to

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

Or

    public ObjectId Id { get; set; }

Or to make your class inheriting from class Entity if you use MongoRepository :

     [BsonIgnoreExtraElements]
     public class Topic : Entity
     {
       [BsonElement("title")]
       public string Name { get; set; }
     }

Upvotes: 4

bombek
bombek

Reputation: 584

I ended up doing this:

public class Topic
{
    public int Id { get; set; }
    public string Name { get; set; }
}

[BsonIgnoreExtraElements]
public class TopicMapper
{
    [BsonElement("title")]
    public string Name { get; set; }
    [BsonElement("id")]
    public int Identity { get; set; }
}

and this:

var list = await col.Find(new BsonDocument()).ToListAsync().ConfigureAwait(false);
        foreach(var doc in list)
        {
            if(doc.Name != null)
               topics.Add(new Topic{
                Id = doc.Identity,
                Name = doc.Name
               });
        }

Upvotes: 1

Related Questions