Reputation: 14736
I am having an issue with serializing BsonDocuments using BsonSerializer.
I am using var bsonDoc = collection.Find(...)
to pull a single document from a MongoDB database.
I then try to serialize it using
var strongTypedDocument = BsonSerializer.Deserialize<MainSDocument>(bsonDoc);
Here is the BsonDocument
{
"MainSPayload" :
{
"GDeets" : { "Id" : 0, "GSerial" : "XX123XX123" }
}
}
Here are the C# classes
[JsonObject(MemberSerialization.OptIn)]
[BsonIgnoreExtraElements]
public class MainSDocument
{
[JsonProperty(Required = Required.Always)]
public MainState MainSPayload
{
get; set;
}
}
[JsonObject(MemberSerialization.OptIn)]
public class MainState
{
[JsonProperty(Required = Required.Always)]
public GDetails GDeets
{
get; set;
}
}
public class GDetails
{
public int Id
{
get; set;
}
public string GSerial
{
get; set;
}
}
The error I am getting is: FormatException: An error occurred while deserializing the GDetails property of class MainState : Element 'Id' does not match any field or property of class GDetails .'
Why is this happening? Why doesn't the element Id
match the int element Id
in the GDetails
class?
Upvotes: 1
Views: 953
Reputation: 4877
Serialization for Id
field has a special workflow that effectively converts this value into how the server side represents it: _id
. To workaround it you can use:
BsonClassMap.RegisterClassMap<GDetails>(c =>
{
c.AutoMap();
c.UnmapField(u => u.Id); // remove default _id workflow
c.MapField(u => u.Id); // add a simple Id field
});
or simpler:
BsonClassMap.RegisterClassMap<GDetails>(c =>
{
c.AutoMap();
c.SetIdMember(null);
});
UPDATE: There is a bit more flexible way. You can configure a new convention and set for what types you will need using it:
var customPack = new ConventionPack();
customPack.Add(new NoIdMemberConvention());
ConventionRegistry.Register("NoIdConvention", customPack, t => t == typeof(GDetails));
also instead the above, you can just add BsonNoId attribute to your class:
[BsonNoId]
public class GDetails
{
public int Id
{
get; set;
}
public string GSerial
{
get; set;
}
}
Upvotes: 1