Antipod Antipod - 1 year ago 128
C# Question

How to ignore null values globally by calling obj.ToBsonDocument() using MongoDB С# 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.

Answer Source

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

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

var anon = new
    Foo = "bar",
    Baz = (string)null,

                            new ConventionPack { new IgnoreIfDefaultConvention(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.