Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

mongodb

bson

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.

like image 856
Antipod Avatar asked Aug 03 '16 15:08

Antipod


3 Answers

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.

like image 88
CodeCaster Avatar answered Oct 07 '22 01:10

CodeCaster


Actually, using IgnoreIfDefaultConvention can cause an unintended behavior due the fact it affects all default values. For instance, values as the list above will not be saved:

  • int = 0
  • decimal = 0
  • bool = false

If you want to ignore only null values, the best approach is IgnoreIfNullConvention.

Here is an example of it:

ConventionRegistry.Register("IgnoreIfNullConvention", new ConventionPack { new IgnoreIfNullConvention(true) }, t => true);
like image 32
Rafael Jusi Avatar answered Oct 07 '22 01:10

Rafael Jusi


You can also apply the [BsonIgnoreIfNull] attribute from the MongoDB.Bson.Serialization.Attributes
namespace to a class field if you don't what that field with a null value to appear in the BSON Document.

public class Person
{
    public string Name { get; set; }

    [BsonIgnoreIfNull]
    public List<string> Children { get; set; }
}
like image 24
Anthony Liriano Avatar answered Oct 07 '22 01:10

Anthony Liriano