azos
azos copied to clipboard
(Slim) Packed DateTimeOffset is equal to MinValue after deserialization
static readonly SlimSerializer serializer = new SlimSerializer();
static byte[] Serialize(object obj)
{
using (var ms = new MemoryStream())
{
serializer.Serialize(ms, obj);
return ms.ToArray();
}
}
static object Deserialize(byte[] data)
{
using (var ms = new MemoryStream(data))
{
return serializer.Deserialize(ms);
}
}
static void Main(string[] args)
{
var dateTimeOffsetNow = DateTimeOffset.Now;
var packedDateTimeOffset = new {Now = dateTimeOffsetNow};
var serializedDateTimeOffset = Serialize(dateTimeOffsetNow);
var serializedPackedDateTimeOffset = Serialize(packedDateTimeOffset);
var deserializedDateTimeOffsetNow = Deserialize(serializedDateTimeOffset);
var deserializedPackedDateTimeOffset = (dynamic) Deserialize(serializedPackedDateTimeOffset);
}
// dateTimeOffsetNow: 6/27/2019 1:02:12 PM +03:00
// deserializedDateTimeOffsetNow: 6/27/2019 1:02:12 PM +03:00
// packedDateTimeOffset.Now: 6/27/2019 1:02:12 PM +03:00
// deserializedPackedDateTimeOffset.Now: 1/1/0001 12:00:00 AM +00:00
@kalteherz can you repeat your test without using the "dynamic"? The test code you have is about serializing an anonymous class, so try it with explicit class (public class A{ public DateTimeOffset Now;}}
@itadapter Same result.
dateTimeOffsetNow: 6/27/2019 3:56:28 PM +03:00
deserializedDateTimeOffsetNow: 6/27/2019 3:56:28 PM +03:00
packedDateTimeOffset.Now: 6/27/2019 3:56:28 PM +03:00
deserializedPackedDateTimeOffset.Now: 1/1/0001 12:00:00 AM +00:00
static readonly SlimSerializer serializer = new SlimSerializer();
static byte[] Serialize(object obj)
{
using (var ms = new MemoryStream())
{
serializer.Serialize(ms, obj);
return ms.ToArray();
}
}
static object Deserialize(byte[] data)
{
using (var ms = new MemoryStream(data))
{
return serializer.Deserialize(ms);
}
}
public class A
{
public DateTimeOffset Now;
}
static void Main(string[] args)
{
var dateTimeOffsetNow = DateTimeOffset.Now;
var packedDateTimeOffset = new A(){ Now = dateTimeOffsetNow };
var serializedDateTimeOffset = Serialize(dateTimeOffsetNow);
var serializedPackedDateTimeOffset = Serialize(packedDateTimeOffset);
var deserializedDateTimeOffsetNow = (DateTimeOffset)Deserialize(serializedDateTimeOffset);
var deserializedPackedDateTimeOffset = Deserialize(serializedPackedDateTimeOffset) as A;
Console.WriteLine($"{nameof(dateTimeOffsetNow)}:\t\t\t{dateTimeOffsetNow.ToString()}");
Console.WriteLine($"{nameof(deserializedDateTimeOffsetNow)}:\t\t{deserializedDateTimeOffsetNow.ToString()}");
Console.WriteLine();
Console.WriteLine($"{nameof(packedDateTimeOffset)}.{nameof(A.Now)}:\t\t{packedDateTimeOffset.Now.ToString()}");
Console.WriteLine($"{nameof(deserializedPackedDateTimeOffset)}.{nameof(A.Now)}:\t{deserializedPackedDateTimeOffset.Now.ToString()}");
}
@kalteherz looks like DateTimeOffset uses custom serialization mechanisms internally, so that is the most probable cause. Will require construction of additional unit test to figure this out. We can also serialize DateTimeOffset ourselves without MSFT ISerializable solution
@itadapter If you solve this problem for the NFX too, it will be great.
@kalteherz NFX is legacy code, you should use .Net Standard Azos instead for current development
I cloned NFX and similar lines of code solved the problem, at first glance:
public override void Write(DateTimeOffset value)
{
Write(value.DateTime);
Write(value.Offset);
}
public override void Write(DateTimeOffset? value)
{
if (value.HasValue)
{
Write(true);
Write(value.Value);
return;
}
Write(false);
}
public override DateTimeOffset ReadDateTimeOffset()
{
var dateTime = ReadDateTime();
var offset = ReadTimeSpan();
return new DateTimeOffset(dateTime, offset);
}
public override DateTimeOffset? ReadNullableDateTimeOffset()
{
var has = ReadBool();
if (has) return ReadDateTimeOffset();
return null;
}
Also added these methods to interfaces and types to Slim.TypeRegistry.
It works for me.
@itadapter The same problem with IntPtr
Just proposed a PR regarding this issue: https://github.com/azist/azos/pull/611 Thanks @kalteherz for the pointer.