polenter / SharpSerializer

SharpSerializer can serialize types like: multidimensional array, nested array, array-of-arrays, polymorphic object (where value is inherited from the property type), generic type, generic listing (i.e. dictionary, collection) and many more, with a single line of code
https://www.sharpserializer.net
Other
114 stars 28 forks source link

DateTimeOffset serialization failure #17

Closed anderslyman closed 2 years ago

anderslyman commented 2 years ago

When serializing/deserializing DateTimeOffset properties, the date is set to the default value of 1/1/0001 12:00:00 AM +00:00. Conversely, DateTime properties work as expected.

LINQPad script: http://share.linqpad.net/i8covu.linq

void Main()
{
    var dtA = new DateTimeOffsetExample { Date = DateTimeOffset.Now };
    var dtB = new DateTimeExample { Date = DateTime.Now };

    var bytesA = ObjectToByteArray(dtA);
    ByteArrayToObject<DateTimeOffsetExample>(bytesA).Dump();

    var bytesB = ObjectToByteArray(dtB);
    ByteArrayToObject<DateTimeExample>(bytesB).Dump();
}

public class DateTimeExample
{
    public DateTime Date { get; set; }
}

public class DateTimeOffsetExample
{
    public DateTimeOffset Date { get; set; }
}

public static byte[] ObjectToByteArray(object obj)
{
    if (obj == null)
    {
        return Array.Empty<byte>();
    }

    using var ms = new MemoryStream();
    var serializer = new SharpSerializer(true);
    serializer.Serialize(obj, ms);

    return ms.ToArray();
}

public static T ByteArrayToObject<T>(byte[] arrBytes)
{
    if (arrBytes == null)
    {
        return default(T);
    }

    using var memStream = new MemoryStream();
    memStream.Write(arrBytes, 0, arrBytes.Length);
    memStream.Seek(0, SeekOrigin.Begin);
    var serializer = new SharpSerializer(true);
    var obj = serializer.Deserialize(memStream);

    return (T)obj;
}

Yields: image

anderslyman commented 2 years ago

PR'd - I realize this repo has seen no activity in 4 years, but it's here if someone wants it.

AntiTenzor commented 2 years ago

PR'd - I realize this repo has seen no activity in 4 years, but it's here if someone wants it.

Thank you very much for this PR! We'll hope it will be merged in main. =)

AntiTenzor commented 2 years ago

There is one more critical error. This serializer does not preserve Kind property.

Let's modify your example:

var dtB = new DateTimeExample { Date = DateTime.UtcNow };

Then

DateTimeExample actualDt = ByteArrayToObject<DateTimeExample>(bytesB);

Now let's examine actualDt.Date.Kind :

if (actualDt.Date.Kind != DateTimeKind.Utc)
    throw new InvalidOperationException($"Expected Kind is UTC, but it is '{actualDt.Date.Kind}'!");
polenter commented 2 years ago

I've just merged the PR of @anderslyman. Thanks! Additional tests report no errors concerning XML serialization of DateTimeKind. However, there are errors during the binary serialization, confirming the problem reported by @AntiTenzor. The problem is extracted there: #20