skip to Main Content

Is it possible for MongoDb to set a DateTimeSerializer for a C# inner object DataTime property in a POCO class using ClassMap without the BsonDateTimeOptions attribute ?

Example :

public class Entity
{
    public string Id { get; init; }
    
    public string Currency { get; init; }
    
    public IEnumerable<InnerEtity> InnerEtities { get; init;}
}
        
public class InnerEtity
{
    //Don't want to use this attribute
    [BsonDateTimeOptions(DateOnly = true)]
    public DateTime Date { get; set; }
        
    public double Value { get; set; }
}

3

Answers


  1. You can specify serialization options in this way:

            BsonClassMap.RegisterClassMap<InnerEtity>(classMap =>
            {
                classMap.AutoMap();
                classMap.GetMemberMap(c => c.Date).SetSerializer(new DateTimeSerializer(dateOnly: true));
            });
    
    Login or Signup to reply.
  2. You can use "imperative" mapping instead of using the attributes, e.g.

    BsonClassMap.RegisterClassMap<InnerEtity>(classMap =>
    {
        classMap.AutoMap();
        classMap.GetMemberMap(c => c.Date).SetSerializer(new DateTimeSerializer(dateOnly: true));
    });
    

    This way, you do not need to use attributes for the mapping and keep the class "MongoDB-agnostic".
    Please be aware that you need to run the code when bootstraping your application so that MongoDB C# Driver already knows the class map when using the entity for the first time.

    Login or Signup to reply.
  3. I think your problem can be solved like this:

    using MongoDB.Bson.Serialization;
    using MongoDB.Bson.Serialization.Conventions;
    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    
    public class Entity
    {
        public string Id { get; init; }
        
        public string Currency { get; init; }
        
        public IEnumerable<InnerEntity> InnerEntities { get; init; }
    }
            
    public class InnerEntity
    {
        public DateTime Date { get; set; }
            
        public double Value { get; set; }
    }
    
    public class EntityClassMap : BsonClassMap<Entity>
    {
        public override void RegisterClassMap(BsonClassMap<Entity> cm)
        {
            cm.AutoMap();
            cm.MapMember(x => x.InnerEntities).SetSerializer(new EnumerableSerializer<InnerEntity>());
        }
    }
    
    public class InnerEntityClassMap : BsonClassMap<InnerEntity>
    {
        public override void RegisterClassMap(BsonClassMap<InnerEntity> cm)
        {
            cm.AutoMap();
            cm.MapMember(x => x.Date).SetSerializer(new CustomDateTimeSerializer());
        }
    }
    
    public class CustomDateTimeSerializer : IBsonSerializer<DateTime>
    {
        public Type ValueType => typeof(DateTime);
    
        public DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            // your custom deserialization logic here 
            // if needed.
            return context.Reader.ReadDateTime();
        }
    
        public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
        {
            // your custom serialization logic here 
            // if needed!
            context.Writer.WriteDateTime(value);
        }
    
        public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
        {
            if (value == null)
            {
                context.Writer.WriteNull();
                return;
            }
    
            if (!(value is DateTime))
            {
                throw new ArgumentException("Value is not a DateTime.");
            }
    
            Serialize(context, args, (DateTime)value);
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            BsonClassMap.RegisterClassMap<Entity>(cm => new EntityClassMap().RegisterClassMap(cm));
            BsonClassMap.RegisterClassMap<InnerEntity>(cm => new InnerEntityClassMap().RegisterClassMap(cm));
    
            //  MongoDB connection 
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search