devshorts
devshorts

Reputation: 8872

Store all dates as BsonDocuments

I have a feeling this is possible but I can't seem to find it. I'd like to configure my mongo driver to make any DateTime object stored as a BsonDocument.

The mongo c# driver lets you set certain conventions globally so you don't need to annotate everything, is this also possible for date time options?

For example, I'd like to remove the following annotation:

[BsonDateTimeOptions(Representation = BsonType.Document)]

From all of my DateTime properties. Can anyone point me in the right direction?

Upvotes: 2

Views: 465

Answers (2)

devshorts
devshorts

Reputation: 8872

Long overdue, but the answer is to use a convention pack and set

ConventionRegistry.Register(
            "Dates as utc documents",
            new ConventionPack
            {
                new MemberSerializationOptionsConvention(typeof(DateTime), new DateTimeSerializationOptions(DateTimeKind.Utc, BsonType.Document)),
            },
            t => true);

Upvotes: 1

Robert Stam
Robert Stam

Reputation: 12187

When I tried to verify that the answer provided by devshorts worked I got a compile time error (because the Add method of ConventionPack, which is being called by the collection initializer syntax, expects an IConvention).

The suggested solution was almost right, and only a slight modification was needed:

ConventionRegistry.Register(
    "dates as documents",
    new ConventionPack
    {
        new DelegateMemberMapConvention("dates as documents", memberMap =>
        {
            if (memberMap .MemberType == typeof(DateTime))
            {
                memberMap .SetSerializationOptions(new DateTimeSerializationOptions(DateTimeKind.Utc, BsonType.Document));
            }
        }),
    },
    t => true);

If we needed to use this convention in more than one place we could package it up in a class, as so:

public class DateTimeSerializationOptionsConvention : ConventionBase, IMemberMapConvention
{
    private readonly DateTimeKind _kind;
    private readonly BsonType _representation;

    public DateTimeSerializationOptionsConvention(DateTimeKind kind, BsonType representation)
    {
        _kind = kind;
        _representation = representation;
    }

    public void Apply(BsonMemberMap memberMap)
    {
        if (memberMap.MemberType == typeof(DateTime))
        {
            memberMap.SetSerializationOptions(new DateTimeSerializationOptions(_kind, _representation));
        }
    }
}

And then use it like this:

ConventionRegistry.Register(
    "dates as documents",
    new ConventionPack
    {
        new DateTimeSerializationOptionsConvention(DateTimeKind.Utc, BsonType.Document)
    },
    t => true);

Upvotes: 3

Related Questions