[CSHARP-2185] Read only properties do not respect custom conventions Created: 10/Feb/18  Updated: 27/Oct/23  Resolved: 11/Dec/18

Status: Closed
Project: C# Driver
Component/s: Serialization
Affects Version/s: 2.5
Fix Version/s: None

Type: Bug Priority: Critical - P2
Reporter: Frédéric Barrière Assignee: Robert Stam
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

netstandard 2.0



 Description   

Imagine a class to store in a collection :

enum MyEnum
{
  Value1
}
 
class MyDoc
{
  public string Id { get; set; }
  public MyEnum Prop { get; set; }
  public MyEnum Prop2
  {
    get { return MyEnum.Value1;  }
  }
}

Mapping is declared as it to allow serialization of read only property :

BsonClassMap.RegisterClassMap<MyDoc>(cm =>
{
  cm.AutoMap();
  cm.MapIdProperty(x => x.Id)
    .SetSerializer(new StringSerializer(BsonType.ObjectId))
    .SetIdGenerator(StringObjectIdGenerator.Instance);
  cm.MapMember(x => x.Prop2);
});

These conventions are added :

var pack= new ConventionPack();
pack.Add(new CamelCaseElementNameConvention());
pack.Add(new EnumRepresentationConvention(BsonType.String));
ConventionRegistry.Register("custom", pack, t => true);

When this instance is inserted into the collection:

var doc = new MyDoc
{
  Prop = MyEnum.Value1
}

Then the resulting document in MongoDB is :

{
  "_id":"5a7f07f1ac141637ec1ba0c9",
  "prop": "Value1",
  "Prop2": 0
}

The conventions are not respected for the read only property Prop2 :

  • its name is not camel case (first letter is upper case)
  • its value is stored with the enum value instead of enum key.


 Comments   
Comment by Robert Stam [ 11/Dec/18 ]

The way conventions work is that they are applied when AutoMap is called.

If you add more members to the class map after AutoMap has already been called the conventions are not considered. In such a case you must configure the new member fully yourself. So you could change your code to:

cm.MapMember(x => x.Prop2)
    .SetElementName("prop2")
    .SetSerializer(new EnumSerializer<MyEnum>(BsonType.String));

Another option you could consider is to add the new member before AutoMap is called:

cm.MapMember(x => x.Prop2);
cm.AutoMap();

That way AutoMap will apply any applicable conventions to Prop2 as well.

Generated at Wed Feb 07 21:41:50 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.