使用protobuf-net.dll
版本1.0.0.280
[当我反序列化DateTime
(包装在对象中)时,日期/时间确定,但是DateTime.Kind
属性为“未指定”
考虑此测试用例以序列化/反序列化DateTime。
[TestMethod] public void TestDateTimeSerialization() { var obj = new DateTimeWrapper {Date = DateTime.UtcNow}; obj.Date = DateTime.SpecifyKind(obj.Date, DateTimeKind.Utc); var serialized = obj.SerializeProto(); var deserialized = serialized.DeserializeProto<DateTimeWrapper>(); Assert.AreEqual(DateTimeKind.Utc, deserialized.Date.Kind); } public static byte[] SerializeProto<T>(this T item) where T : class { using (var ms = new MemoryStream()) { Serializer.Serialize(ms, item); return ms.ToArray(); } } public static T DeserializeProto<T>(this byte[] raw) where T : class, new() { using (var ms = new MemoryStream(raw)) { return Serializer.Deserialize<T>(ms); } }
断言失败,种类==
Unspecified
由于protobuf-net
未序列化此属性(请参见下文),一种解决方案是假设在客户端显示日期时DateTimeKind
等于Utc(仅当您know应该为UTC时)课程):
public static DateTime ToDisplayTime(this DateTime utcDateTime, TimeZoneInfo timezone) { if (utcDateTime.Kind != DateTimeKind.Utc)//may be Unspecified due to serialization utcDateTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Utc); DateTime result = TimeZoneInfo.ConvertTime(utcDateTime, timezone); return result; }
这省去了您分配给接收方的每个
DateTime
属性的麻烦。
使用protobuf-net.dll版本1.0.0.280,当我反序列化DateTime(包装在对象中)时,日期/时间确定,但是DateTime.Kind属性为'Unspecified'将此测试用例考虑为...
protobuf.net必须保持与protobuf二进制格式的兼容性,该格式是为Java日期/时间数据类型设计的。 Java中没有Kind
字段->没有protobuf二进制格式的Kind
支持-> Kind
未通过网络传输。或类似的东西。
作为Ben答案的扩展...严格来说,protobuf 有
另一种解决方案是更改DTO的kind属性,并将其始终设置为UTC。这可能不适用于所有应用程序,但对我有用
这里是解决方法的实现。让我知道您是否能找到更好的解决方案。谢谢!
protobuf使用UtcKind自动反序列化DateTime可能更有意义,那样的话,如果您使用Utc作为基础,无论如何我都认为这是最佳实践,则不会有任何问题。
假设您只需要一个[ProtoContract(SkipConstructor = true)]
public class MyClass
{
[ProtoMember(3)]
[XmlIgnore]
private ProtoDateTime _timestampWrapper { get; set; }
[ProtoIgnore]
public DateTime Timestamp
{
get
{
return ProtoDateTime.getValue(ref _timestampWrapper);
}
set
{
return ProtoDateTime.setValue(out _timestampWrapper, value);
}
}
[ProtoMember(4)]
[XmlIgnore]
private ProtoDateTime _nullableTimestampWrapper { get; set; }
[ProtoIgnore]
public DateTime? NullableTimestamp
{
get
{
return ProtoDateTime.getValueNullable(ref _nullableTimestampWrapper);
}
set
{
return ProtoDateTime.setValue(out _nullableTimestampWrapper, value);
}
}
}
(即DateTimeKind
或UTC
),有一个简单的(虽然不是很漂亮的)解决方案。