[CSHARP-2553] [BsonIgnore] in deserialization Created: 18/Mar/19  Updated: 07/Apr/23  Resolved: 25/Jun/20

Status: Closed
Project: C# Driver
Component/s: BSON
Affects Version/s: 2.8.0
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Daniel Almeida Assignee: Wan Bachtiar
Resolution: Done Votes: 1
Labels: question, rfw
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

.NET Core 2.2 on Windows 8



 Description   

Consider the following implementation:

public class Foo
{
	public ObjectId Id { get; set; }
	public string Name { get; set; }
}
 
public class Bar
{
	public ObjectId Id { get; set; }
	public ObjectId FooId { get; set; }
 
	[BsonIgnore]
	public Foo Foo { get; set; }
}

When saving a Bar instance into the Collection the Foo property is ignored as expected. But the property is also being ignored when deserializing Bar.

 

 

return await db.GetCollection<Bar>("Bar")
	.Aggregate()
	.Lookup("Foo", "FooId", "_id", "Foo")
	.Unwind("Foo")
	.As<Bar>()
	.ToListAsync(cancellationToken);

The code above does not work since the driver is ignoring the property Foo of Bar's class.

 

'Element 'Foo' does not match any field or property of class Bar.'

Why [*BsonIgnored*] is being used in deserialization?

 

Interestingly, if a change the Bar class as following (using ShouldSerialize method) the code works as expected:

public class Bar
{
	public ObjectId Id { get; set; }
	public ObjectId FooId { get; set; }
 
	public Foo Foo { get; set; }
	public bool ShouldSerializeFoo() { return false; }
}

Any thoughts on that?



 Comments   
Comment by Rachelle Palmer [ 25/Jun/20 ]

Hi there, thank you for reaching out to MongoDB. As this sounds more like a support issue, I wanted to give you some resources to get this question answered more quickly:

  • our MongoDB support portal, located at support.mongodb.com
  • our MongoDB community forums, located here
  • If you are an Atlas customer, there is free support offered 24/7 in the lower right hand corner of the UI.

Thank you!
Rachelle

Comment by Róger Lopes [ 02/Jun/20 ]

Hi. I am facing the same problem here. I can't create a new "LookedUpClass". I want the property to be ignored when I send the object to the database, but I need it when I LookUp it, which is not happening when I have BsonIgnore. I guess my solution for now will be the ShouldSerialize method that Danield mentioned.

Comment by Daniel Almeida [ 18/Apr/19 ]

Hi Wan,

I appreciate your time answering the question, but here are some considerations.

According to the API Documentation

BsonIgnoreAttribute Indicates that this field or property should be ignored when this class is serialized.

The one consuming the API should trust in its docs, and will not know the magic happening underneath.

 

The output document of this Lookup/Unwind exemple should matches Bar. The problem is that Bar.Foo is not being ignored, it is being removed when constructing the "class map".

The given solution would be suitable for simple scenarios like the one I gave, but in my real case I am working with multiple degrees of polymorphic classes that  makes impossible to use it like that.

As i said the ShouldSerialize returning false is working great in my scenario and I am no longer in doubt about how to use the driver.

I opened this thread to discus with mongo team what could be done to make the driver better. Changing the behavior of [BsonIgnore] now might not be the best option since it could create bugs in some users implementation. I better aproche would be create a new constructor that receives a parameter indicating whether or not it should be ignored on deserialization. Like {{[BsonIgnore(false)] }}

Regards,

Comment by Wan Bachtiar [ 26/Mar/19 ]

> Any thoughts on that?

Hi Daniel,

[BsonIgnore] means that the property is ignored when constructing the class map (and therefore is not part of the class map).

The issue here is because the shape of the output documents of Lookup/Unwind stage matches neither Foo nor Bar, but a combination of the two. The solution is to create a new class for the output of the aggregation. For example:

    public class Bar
    {
        public ObjectId Id { get; set; }
        public ObjectId FooId { get; set; }
        public string Name { get; set;}
    }
    // Use this for the aggregation output deserialization
    public class BarOutput: Bar
    {
        public Foo Foo { get; set; }
    }

Please note that the CSHARP project is for reporting bugs or feature suggestions for the MongoDB .NET/C# driver. If you have follow-up questions on the use of the C# driver, please post a question on mongodb-user group with the relevant information.

Regards,
Wan.

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