Yes I did.

This is my entire classmap setup for the PhoneBookContact object:

BsonClassMap.RegisterClassMap<PhoneBookContact>(classMap =>
{
    classMap.AutoMap();
    classMap.UnmapMember(m => m.Categories);
    classMap.UnmapMember(m => m.PhoneBooks);
    classMap.MapProperty(m => m.NumberOfTelephoneNumbers);
    classMap.MapProperty(x => x.ManagerId).SetSerializer(new StringSerializer(BsonType.ObjectId));
    //classMap.MapProperty(x => x.Numbers[0].Number).SetSerializer(new StringSerializer(BsonType.ObjectId));

    classMap.MapProperty(x => x.PhoneBookIds)
        .SetSerializer(
            new EnumerableInterfaceImplementerSerializer<List<string>, string>(
            new StringSerializer(BsonType.ObjectId)));
    classMap.MapProperty(x => x.CategoryIds)
        .SetSerializer(
            new EnumerableInterfaceImplementerSerializer<List<string>, string>(
            new StringSerializer(BsonType.ObjectId)));
});

And I register my custom convention as follows:

var pack = new ConventionPack
{
    new IgnoreExtraElementsConvention(true),
    new StringObjectIdGeneratorConvention()
};
ConventionRegistry.Register("My Solution Conventions", pack, t => true);

With StringObjectIdGeneratorConvention being:

internal class StringObjectIdGeneratorConvention : ConventionBase, IPostProcessingConvention
{
    /// <summary>
    /// Applies a post processing modification to the class map.
    /// </summary>
    /// <param name="classMap">The class map.</param>
    public void PostProcess(BsonClassMap classMap)
    {
        var idMemberMap = classMap.IdMemberMap;
        if (idMemberMap == null || idMemberMap.IdGenerator != null)
            return;
        if (idMemberMap.MemberType == typeof(string))
        {
            idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance).SetSerializer(new StringSerializer(BsonType.ObjectId));
        }
    }
}

I’m using conventions and ClassMaps because I cannot add a MongoDb dependency to the POCO object itself.