[CSHARP-2325] MongoDB C# Driver (2.7) and serialization issues Created: 12/Jul/18  Updated: 09/Nov/22  Resolved: 09/Nov/22

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

Type: Bug Priority: Minor - P4
Reporter: Paolo Lombardo Assignee: James Kovacs
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

.net framework 4.5


Attachments: Zip Archive TestMongoDbSerialization.zip    
Issue Links:
Duplicate
duplicates CSHARP-1996 Subclass with no additional propertie... Closed

 Description   

The following post is more or less a copy-paste of a question I posted on stackoverflow.

My colleagues suggested me to also post a question here on JIRA, so here I am.

I also provided a minimalistic sample code to reproduce the error.

Link to SO: https://stackoverflow.com/questions/51285902/mongodb-c-sharp-driver-2-7-and-serialization-issues

===== ISSUE AND QUESTION ====

I'm currently having a strange issue with the latest mongodb c# driver (2.7), inheritance and serialization.I'm currently having a strange issue with the latest mongodb c# driver (2.7), inheritance and serialization.

Here is a super simplified class hierarchy that I'm using:

public abstract class BaseClass { 
  public Guid Id { get; private set; }
  protected BaseClass(Guid id) { Id = id; } 
}     
 
public class DerivedClass : BaseClass 
{ 
  public DerivedClass(Guid id) : base(id) {} 
}

When I try to register the class for mongo serialization, I am getting an error:

var type = typeof(DerivedClass);
if (BsonClassMap.IsClassMapRegistered(type)) 
  return;
var cm = new BsonClassMap(type); cm.AutoMap();
BsonClassMap.RegisterClassMap(cm);

The error is:

The memberInfo argument must be for class DerivedClass, but was for class BaseClass.    Parameter name: memberInfo

Now, and this is where things start to get weird, when I tried to understand what was happening I made some changes to the BaseClass or the DerivedClass.

ANY of the two changes listed below will make the `RegisterClassMap` method work without errors...

change 1: adding a second, unused property on BaseClass

public abstract class BaseClass { 
  public Guid Id { get; private set; } 
  public string Test { get; }
  protected BaseClass(Guid id) { Id = id; } 
}

change 2: changing the Id property to have a non-private setter (any other works)

public abstract class BaseClass { 
  public Guid Id { get; protected set; }
  protected BaseClass(Guid id) { Id = id; } 
} 

THE QUESTION
My question is... what is happening? While I may agree that for the serializer you should have an accessible setter for every property on the class that you want to map (in this case, DerivedClass), why the case #1 is actually not giving any error?

 



 Comments   
Comment by Wan Bachtiar [ 22/Jan/19 ]

why the case #1 is actually not giving any error?

Hi sh0uzama,

Thanks for reporting this issue, and providing the minimalistic sample code as well. Based on the code, I can see that this is a bug in the constructor mapping.

This is all happening in Apply() method in ImmutableTypeClassMapConvention.cs#L29.

For case #1, the call to classMap.MapConstructor() is skipped when there's an additional (unused) property because the method only consider constructors that have sufficient parameters to initialise the base properties. In other words, the addition of Unused is making the code skip trying to map the DerrivedClass constructor.

For case #2, as you have touched upon, the call to classMap.MapConstructor() is skipped because DerrivedClass has been found to have a mutable inherited property Id.

The next step here is to patch BsonClassMap.MapConstructor() to handle this case.

Regards,
Wan.

Comment by David Mumladze [ 12/Oct/18 ]

Has this been abandoned or still there's a hope someone from MongoDB will provide answer?

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