Search code examples
c#mongodbbson

How to ignore null values globally by calling obj.ToBsonDocument() using MongoDB C# driver?


Prehistory: I have a class hierarchy (a big one) which was generated from an XML schema (XSD).

MyObj obj;

Nowadays: I need to parse a string value, which is actually an XML to an object using the generated class hierarchy and then I need to put the object into MongoDB. The code is:

private BsonDocument XmlToBson(string content)
{
    MyObj obj;
    using (var reader = new StringReader(content))
    {
        var serializer = new XmlSerializer(typeof(MyObj));
        obj = (MyObj) serializer.Deserialize(reader);
    }

    return obj.ToBsonDocument();
}

The problem: I have a lot of null children objects in the hierarchy, it looks like this in Robomongo:

Object which is null is added

I want to avoid adding null objects into the database. I know I can ignore them one by one, like described here Ignoring Default Values by using attributes or lambda expressions. But because the hierarchy is big and complex I do not like this approach. I am to lazy to list all the properties which have to be ignored when they have null values. Even more, the class can be regenerated in future and it will be a nightmare to support the list of properties which have to be ignored.

Question: How can I achieve the goal and ignore the null values globally no matter where the object is in hierarchy? I am working with MongoDB C# driver ver. 2.2.


Solution

  • You can apply the effects of most attributes to all properties while serializing by registering convention packs.

    Below the IgnoreIfNullConvention is registered, implicitly applying the [IgnoreIfNull] attribute to all properties while serializing and deserializing.

    var anon = new
    {
        Foo = "bar",
        Baz = (string)null,
    };
    
    ConventionRegistry.Register("Ignore", 
                                new ConventionPack 
                                { 
                                    new IgnoreIfNullConvention(true) 
                                }, 
                                t => true);
    
    var bsonDocument = anon.ToBsonDocument();
    

    This will yield a document only containing the Foo key.

    When desired, you can also Remove() this convention pack by name after serialization.