MongoDB C#:DateTimeOffset到BsonType DateTime的序列化程序

214 篇文章 12 订阅

目录

介绍

背景

使用代码

兴趣点


目前不支持将DateTimeOffset序列化为MongoDB中的DateTime。该解决方案将向您展示它是如何工作的。

介绍

如果您需要DateTimeOffsets在模型中使用,并且希望将其存储为BsonType DateTime,则会出现“ 'DateTime' is not a valid DateTimeOffset representation.“ Cannot deserialize a 'DateTimeOffset' from BsonType 'DateTime'.” 等错误

背景

我们在某些模型中使用DateTimeOffsets,因为我们有一个基于XML的导入运行,其值包含DateTimeOffsetsXXXXXX +0100)或类似值。虽然我们希望这些值能作为DateTime被储存在MongoDB中。我们不太关心偏移信息,存储的UTC对我们来说很好。

您可以轻松在MongoDB中创建自己的DateTimeOffset序列化器并将其注册为DateTimeOffset序列化器。我会告诉你如何处理。

使用代码

您可以查看MongoDB C#客户端的源代码,看看如何构建DateTimeSerializerDateTimeOffset序列化器,并调整其中的内容。最终的序列化程序可能如下所示:

public class DateTimeOffsetSupportingBsonDateTimeSerializer : StructSerializerBase<DateTimeOffset>, 
                 IRepresentationConfigurable<DateTimeOffsetSupportingBsonDateTimeSerializer>
{
    private BsonType _representation;
    private string StringSerializationFormat = "YYYY-MM-ddTHH:mm:ss.FFFFFFK";

    public DateTimeOffsetSupportingBsonDateTimeSerializer() : this(BsonType.DateTime)
    {
    }

    public DateTimeOffsetSupportingBsonDateTimeSerializer(BsonType representation)
    {
        switch (representation)
        {
            case BsonType.String:
            case BsonType.DateTime:
                break;
            default:
                throw new ArgumentException(string.Format("{0} is 
                not a valid representation for {1}", representation, this.GetType().Name));
        }

        _representation = representation;
    }

    public BsonType Representation => _representation;

    public override DateTimeOffset Deserialize(BsonDeserializationContext context, 
                                               BsonDeserializationArgs args)
    {
        var bsonReader = context.Reader;
        long ticks;
        TimeSpan offset;

        BsonType bsonType = bsonReader.GetCurrentBsonType();
        switch (bsonType)
        {
            case BsonType.String:
                var stringValue = bsonReader.ReadString();
                return DateTimeOffset.ParseExact
                    (stringValue, StringSerializationFormat, DateTimeFormatInfo.InvariantInfo);

            case BsonType.DateTime:
                var dateTimeValue = bsonReader.ReadDateTime();
                return DateTimeOffset.FromUnixTimeMilliseconds(dateTimeValue);

            default:
                throw CreateCannotDeserializeFromBsonTypeException(bsonType);
        }
    }

    public override void Serialize
       (BsonSerializationContext context, BsonSerializationArgs args, DateTimeOffset value)
    {
        var bsonWriter = context.Writer;

        switch (_representation)
        {
            case BsonType.String:
                bsonWriter.WriteString(value.ToString
                      (StringSerializationFormat, DateTimeFormatInfo.InvariantInfo));
                break;

            case BsonType.DateTime:
                bsonWriter.WriteDateTime(value.ToUnixTimeMilliseconds());
                break;

            default:
                var message = string.Format("'{0}' is not a valid 
                              DateTimeOffset representation.", _representation);
                throw new BsonSerializationException(message);
        }
    }

    public DateTimeOffsetSupportingBsonDateTimeSerializer WithRepresentation(BsonType representation)
    {
        if(representation == _representation)
        {
            return this;
        }
        return new DateTimeOffsetSupportingBsonDateTimeSerializer(representation);
    }

    IBsonSerializer IRepresentationConfigurable.WithRepresentation(BsonType representation)
    {
        return WithRepresentation(representation);
    }

    protected Exception CreateCannotDeserializeFromBsonTypeException(BsonType bsonType)
    {
        var message = string.Format("Cannot deserialize a '{0}' from BsonType '{1}'.",
            BsonUtils.GetFriendlyTypeName(ValueType),
            bsonType);
        return new FormatException(message);
    }
}

生成的序列化程序可以处理DateTimeOffsets/stringsDateTimes(您也可以省略string表示部分)的序列化。您可以在顶部添加您感兴趣的任何逻辑。要注册新的序列化程序,您应该在开始使用MongoCollection之前调用以下内容。

BsonSerializer.RegisterSerializer<DateTimeOffset>(new DateTimeOffsetSupportingBsonDateTimeSerializer());

准备好了

兴趣点

DateTimes时间在MongoDb中表示为自unix纪元以来的毫秒数。.NET框架现在内置了使用这些值从和到DateTimeOffset进行转换的支持

因此,无论您的DateTimeOffset值是2018-11-24T14:40:23+05:00还是2018-11-24T09:40:23+00:00,它都会在MongoDB中生成相同的DateTime

 

原文地址:https://www.codeproject.com/Tips/1268086/MongoDB-Csharp-Serializer-for-DateTimeOffset-to-Bs

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值