[SOLVED] Date serialization with InvariantConverter

This closed ticket looks like it does not work in some cases: [IMPLEMENTED] Squidex.ClientLibrary: Json serializes dates to incorrect format

I’m using the Squidex.ClientLibrary nuget version 3.9.0

Setting DateTime.Now to a property makes it not serialize properly for some reason.

For example, TimeOne was set in the UI to now, while TimeTwo was set in code:
item.TimeTwo = DateTime.Now;
Result:

"TimeOne": {
	"iv": "2019-09-20T17:54:12Z"
},
"TimeTwo": {
	"iv": "2019-09-24T10:43:20.8948344-04:00"
}

My solution was to copy most of the invariantConverter but extend ISODateConverter, but I’m sure something more elegant can be done.

public sealed class DateInvariantConverter : IsoDateTimeConverter
    {
        public DateInvariantConverter()
        {
            base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ssZ";
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteStartObject();
            writer.WritePropertyName("iv");

            base.WriteJson(writer, value, serializer);

            writer.WriteEndObject();
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            reader.Read();

            if (reader.TokenType != JsonToken.PropertyName || !string.Equals(reader.Value.ToString(), "iv", StringComparison.OrdinalIgnoreCase))
            {
                throw new JsonSerializationException("Property must have a invariant language property.");
            }

            reader.Read();

            var result = serializer.Deserialize(reader, objectType);

            reader.Read();

            return result;
        }

        public override bool CanConvert(Type objectType)
        {
            return false;
        }
    }

Using this converter it works properly. The deserialization is just copied, it does not have a problem.

Strange, but the tests seem to be green. Your solution is not the best idea I think because it would not apply to nested properties and non-invariant fields.

Could you create a small reproducable, e.g. as a PR for the unit tests?

I can reproduce a different problem with the tests. The following test passes:

        [Fact]
        public void Should_serialize_local_datetime_to_iso8601_utc_with_ms()
        {
            var utcTime = new DateTime(634292263478068039);

            var source = new MyClass<DateTime>
            {
                Value = utcTime.ToLocalTime()
            };

            var serialized = source.ToJson();

            Assert.Contains("2010-12-29T13:32:27.8068039Z", serialized);
        }

But the value 2010-12-29T13:32:27.8068039Z, although being a valid ISO value, is not accepted as valid by squidex (tested on the cloud version)

The decimal points to the seconds is the issue.

Yes, the reason is that milliseconds are afaik not ISO8601, but an extended format.

So what would be the solution?

It is on the way…https://github.com/Squidex/squidex-samples/commit/77ffb7f7b2ed1690b0d3141001ba4dc10542f75a

1 Like

Does it solve your initial problem?

I believe it would, but I don’t see how this can work with the InvariantConverter. Can you enlighten me?

To serialize or deserialize the actual value I use the serializer again: https://github.com/Squidex/squidex-samples/blob/master/csharp/Squidex.ClientLibrary/Squidex.ClientLibrary/InvariantConverter.cs#L20

so the serializer picks then the UTCIsoDateTimeConverter because of the CanConvert: https://github.com/Squidex/squidex-samples/blob/master/csharp/Squidex.ClientLibrary/Squidex.ClientLibrary/Utils/UTCIsoDateTimeConverter.cs#L37

I checked out master, built the nuget, updated it, and still the same format with milliseconds.

Really? The tests are green :frowning:

My bad. I was verifying with JsonConvert.SerializeObject(x) instead of x.ToJson()

Your fix does work

I saw you tagged the latest commit to 3.9 though, it was already 3.9 before. That would be something to verify

I fixed the tag as 3.10

1 Like