如何通过 ProtoBuf-net 使用 DateTimeKind 选项序列化 DateTime 字段

Posted

技术标签:

【中文标题】如何通过 ProtoBuf-net 使用 DateTimeKind 选项序列化 DateTime 字段【英文标题】:How to serialize the DateTime field with DateTimeKind option through ProtoBuf-net 【发布时间】:2019-07-03 05:10:47 【问题描述】:

如何通过 ProtoBuf 使用 DateTimeKind 选项序列化日期时间字段。反序列化时,我想要带有 DateTimeKind 选项的日期时间字段。

我知道我们可以通过添加一个额外的属性来将反序列化的值转换为 UTC 格式来实现这一点。

例如,我有一个名为 UtcDateTime 的日期时间字段。它具有 UTC 类型格式的值。当序列化和反序列化这个值时,我得到了正确的结果,但它未能检索到日期时间类型选项。

这是我的示例代码:

[ProtoIgnore]                
public DateTime UtcDateTime  get; set; 

[ProtoMember(3)]           
public DateTime DateTimeValue           

    get  return UtcDateTime ; 
    set  UtcDateTime = DateTime.SpecifyKind(value, DateTimeKind.Utc);    
 

现在考虑我的情况,我的应用程序有很多这样的日期时间字段。我不需要在所有地方添加额外的属性,而是需要一个通用的解决方案来实现这一点。如果可能,请解释如何使用示例 C# 逻辑来实现这一点。提前致谢。

【问题讨论】:

【参考方案1】:

在序列化或反序列化任何内容之前包含此代码以运行:

RuntimeTypeModel.Default.IncludeDateTimeKind = true;

现在你的合约就可以这么简单了(不需要加倍属性):

[ProtoMember(3)]           
public DateTime DateTimeValue  get; set; 

并且DateTimeKind的值会被自动读写。

兼容性问题

值得注意的是,原始协议缓冲区规范不包括 DateTimeKind(它特定于 .NET)——请参阅 protobuf-net does not deserialize DateTime.Kind correctly。在 protobuf-net v2.1.0 中选择支持序列化 DateTimeKind 是 added。

如果你与另一个系统交换这些消息,除非另一端使用 protobuf-net 并将IncludeDateTimeKind 设置为true,否则它将无法工作。

【讨论】:

澄清:“协议缓冲区”规范根本没有涉及; protobuf-net 在某些时候添加了这个,但建议使用众所周知的类型(使用 DataFormat.WellKnown;这使用较新的“时间戳”布局);众所周知的类型不支持任何“种类”的概念

以上是关于如何通过 ProtoBuf-net 使用 DateTimeKind 选项序列化 DateTime 字段的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式确定类型是不是可以通过 protobuf-net 本地序列化?

如何将 protobuf-net 与通过 ASP.NET Web Reference 生成的类一起使用,同时避免代码重复?

protobuf-net 如何序列化 DateTime?

尝试使用 protobuf-net 通过 gRPC-Web 进行 Azure AD 身份验证

如何在 protobuf-net 中启用字符串实习?

如何在 Protobuf-net 中动态添加 Proto 成员