[CSHARP-909] New [BsonIgnoreIfNoElements] attribute Created: 14/Feb/14  Updated: 05/Apr/19  Resolved: 20/Mar/14

Status: Closed
Project: C# Driver
Component/s: Feature Request
Affects Version/s: 1.8.3
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: ??????? ??????? ??????? Assignee: Unassigned
Resolution: Done Votes: 0
Labels: driver
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

any



 Description   

Hi,

I have to serialize the following class with C# driver:

class Sample
{
    [BsonId]
    public object id {get;set;}
    public string name {get;set}
    public Sample2 sample2 {get;set;}
}
 
class Sample2
{
    [BsonIgnoreIfNull]
    public DateTime? DealDate { get; set; }
 
    [BsonIgnoreIfNull]
    public DateTime? FinishDate { get; set; }
}

but I want to ignore sample2 field if this subdoc has no fields (if both dates are null).

For now I can use ShouldSerializesample2, but i would like to implement that with some attribute like [BsonIgnoreIfNoElements]. If json has complex structure with nested nullable elements in subdocs it will be best solution.

It's an open question how often this situation arises. Maybe this attribute deserves implementation. What's your opinion?



 Comments   
Comment by ??????? ??????? ??????? [ 17/Mar/14 ]

Good solution, thanks.

Comment by Robert Stam [ 21/Feb/14 ]

I don't think we can implement a feature like this efficiently because serialization is a one pass operation. By the time we are in a position to realize that the serialized form of sample2 is an empty document we've already serialized it and it's too late.

But you can easily accomplish what you want using the existing support for [BsonIgnoreIfDefault]. The trick is to set the default value for your sample2 property to an instance of Sample2 that is known to serialize as an empty document (i.e. one with all fields null). The only rub is that you can't set the default value using attributes alone because all arguments to an attribute must be compile time constants, so you need to use a bit of code to set the default value.

Add the [BsonIgnoreIfDefault] attribute to your Sample class declaration like this:

class Sample
{
    [BsonId]
    public object id { get; set; }
    public string name { get; set; }
    [BsonIgnoreIfDefault]
    public Sample2 sample2 { get; set; }
}

And use the following snippet of code to run once while your program is starting up:

BsonClassMap.RegisterClassMap<Sample>(cm =>
{
    cm.AutoMap();
    cm.GetMemberMap(c => c.sample2).SetDefaultValue(new Sample2());
});

AutoMap does all of the work of setting up the class map, and all you need to do is call SetDefaultValue.

One final note: for this to work properly your Sample2 class must implement Equals (which you might want to do anyway for other reasons).

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