概述
目录
介绍
背景
使用代码
兴趣点
目前不支持将DateTimeOffset序列化为MongoDB中的DateTime。该解决方案将向您展示它是如何工作的。
介绍
如果您需要DateTimeOffsets在模型中使用,并且希望将其存储为BsonType DateTime,则会出现“ 'DateTime' is not a valid DateTimeOffset representation.”或“ Cannot deserialize a 'DateTimeOffset' from BsonType 'DateTime'.” 等错误
背景
我们在某些模型中使用DateTimeOffsets,因为我们有一个基于XML的导入运行,其值包含DateTimeOffsets(XXXXXX +01:00)或类似值。虽然我们希望这些值能作为DateTime被储存在MongoDB中。我们不太关心偏移信息,存储的UTC对我们来说很好。
您可以轻松在MongoDB中创建自己的DateTimeOffset序列化器并将其注册为DateTimeOffset序列化器。我会告诉你如何处理。
使用代码
您可以查看MongoDB C#客户端的源代码,看看如何构建DateTimeSerializer或DateTimeOffset序列化器,并调整其中的内容。最终的序列化程序可能如下所示:
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从/到strings和DateTimes(您也可以省略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
最后
以上就是年轻世界为你收集整理的MongoDB C#:DateTimeOffset到BsonType DateTime的序列化程序介绍背景使用代码兴趣点的全部内容,希望文章能够帮你解决MongoDB C#:DateTimeOffset到BsonType DateTime的序列化程序介绍背景使用代码兴趣点所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复