猿问

在 c# mongodb 驱动程序中,如何将序列化程序中的 dateOnly

我有一个具有类型属性(假设它被称为X)的模型DateTime?。

我想设置,[BsonDateTimeOptions(DateOnly = true)]但在 mongo c# 驱动程序中使用类映射器,如:


BsonClassMap.RegisterClassMap<MyModel>(cm =>

{

    cm.AutoMap();

    cm.MapMember(c => c.X).SetSerializer(new DateTimeSerializer(dateOnly: true));

});

但由于某种原因,我收到一个错误,因为该属性是Nullable,对于普通DateTime类型,它可以正常工作。


为什么我需要这个,因为我X只需要在没有时区的情况下将值保存为日期。


我已经尝试构建自定义序列化程序,但是在反序列化时出现错误:


ReadBsonType 只能在 State 为 Type 时调用,不能在 State 为 Value 时调用


这是自定义序列化程序:


public class DateTimeNullableSerialzier : DateTimeSerializer, IBsonSerializer

{

    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)

    {

        if (context.Reader.CurrentBsonType == BsonType.Null)

            return null;


        return base.Deserialize(context, args);

    }


    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)

    {

        if (value is null)

            context.Writer.WriteNull();

        else

            base.Serialize(context, args, (DateTime)value);

    }

}


幕布斯6054654
浏览 240回答 2
2回答

暮色呼如

如果有人正在阅读这篇文章并遇到同样的问题,那么实际上有一种方法可以在不实现自己的序列化程序的情况下做到这一点。不过,这是 2.x 版本的驱动程序。默认情况下,mongo 将NullableSerializer<T>用于您的DateTime?字段,但默认情况下没有设置 dateOnly。但是,NullableSerializer<T>只需为该<T>类型包装一个普通的序列化程序,并且有一种方法可以为其提供您自己配置为使用 dateOnly 的实例:var dateSerializer = new DateTimeSerializer(dateOnly: true);var nullableDateOnlySerializer = new NullableSerializer<DateTime>().WithSerializer(dateSerializer));BsonClassMap.RegisterClassMap<MyModel>(cm =>{&nbsp; &nbsp; cm.AutoMap();&nbsp; &nbsp; cm.MapMember(c => c.X).SetSerializer(nullableDateOnlySerializer);});

白衣非少年

实际上,我如何实现序列化程序是问题所在,在进行了一些修复后,它可用于任何可为空的 DateTime 属性(DateTime?)并接受与中相同的构造函数参数DateTimeSerializer(但由于某种原因不适用于 DateTime 类型):public class DateTimeNullableSerializer : IBsonSerializer{&nbsp; &nbsp; public Type ValueType { get; }&nbsp; &nbsp; private DateTimeSerializer dateTimeSerializer;&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; public DateTimeNullableSerializer()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ValueType = typeof(DateTime?);&nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer = new DateTimeSerializer(DateTimeKind.Utc, BsonType.DateTime);&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="dateOnly">if set to <c>true</c> [date only].</param>&nbsp; &nbsp; public DateTimeNullableSerializer(bool dateOnly)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ValueType = typeof(DateTime?);&nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer = new DateTimeSerializer(dateOnly);&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="dateOnly">if set to <c>true</c> [date only].</param>&nbsp; &nbsp; /// <param name="representation">The representation.</param>&nbsp; &nbsp; public DateTimeNullableSerializer(bool dateOnly, BsonType representation)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ValueType = typeof(DateTime?);&nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer = new DateTimeSerializer(dateOnly, representation);&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="representation">The representation.</param>&nbsp; &nbsp; public DateTimeNullableSerializer(BsonType representation)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ValueType = typeof(DateTime?);&nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer = new DateTimeSerializer(DateTimeKind.Utc, representation);&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="kind">The kind.</param>&nbsp; &nbsp; public DateTimeNullableSerializer(DateTimeKind kind)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ValueType = typeof(DateTime?);&nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer = new DateTimeSerializer(kind, BsonType.DateTime);&nbsp; &nbsp; }&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Initializes a new instance of the <see cref="T:DateTimeNullableSerializer" /> class.&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="kind">The kind.</param>&nbsp; &nbsp; /// <param name="representation">The representation.</param>&nbsp; &nbsp; public DateTimeNullableSerializer(DateTimeKind kind, BsonType representation)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; ValueType = typeof(DateTime?);&nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer = new DateTimeSerializer(kind, representation);&nbsp; &nbsp; }&nbsp; &nbsp; public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (context.Reader.CurrentBsonType == BsonType.Null)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.Reader.ReadNull();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return dateTimeSerializer.Deserialize(context, args);&nbsp; &nbsp; }&nbsp; &nbsp; public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (value is null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.Writer.WriteNull();&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dateTimeSerializer.Serialize(context, args, (DateTime)value);&nbsp; &nbsp; }}
随时随地看视频慕课网APP
我要回答