I reflected the JSON.NET JavaScriptDateTimeConverter class code, copied it, and renamed the class AS3DateTimeConverter so that I could modify it to format DateTime objects in a more precise and strongly-typed manor.
I have it output a type according to how JSON.NET outputs strongly-typed objects like so:
{"$type":"System.DateTime, mscorlib","ticks":0}
The overridden WriteJson method of the JsonConverter runs to produce that value.
However, when I try to deserialize the string using the exact same settings with the same converter, the overridden ReadJson method never gets a chance to run and construct a DateTime from the ticks property, because the following errors occurs:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.DateTime' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.
To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'ticks', line 1, position 45.
Is this some kind of bug or limitation, which will not allow me to revive a DateTime type because it is a value-type? Or am I missing something?
Here are the serialization settings:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
settings.ConstructorHandling = ConstructorHandling.Default;
settings.TypeNameHandling = TypeNameHandling.All;
settings.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
settings.DateParseHandling = DateParseHandling.DateTime;
settings.Converters.Add( new AS3DateTimeConverter() );
//settings.Binder = new AS3SerializationBinder();
string s = JsonConvert.SerializeObject( new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ), settings );
object o = JsonConvert.DeserializeObject( s, settings ); //s = "{\"$type\":\"System.DateTime, mscorlib\",\"ticks\":0}" //ERROR OCCURS HERE
"$type":"System.DateTime", the converter's CanConvert method is never called with that type, and the converter's ReadJson method is never called. It's as though it's not even trying to use my converter or even testing to see if it can be used. Perhaps it's a binding issue, but I thought that was automatic. - Triynko{"$type":"mynamespace.DateTimeWrapper","ticks":0}is produced by the serialization, but oddly enough, upon attempting to deserialize the string, the CanConvert method of my JsonConverter is called, but it receives an integer type instead of the mynamespace.DateTimeWrapper type. I find that odd. It's as thought it's ignoring the "$type" embedded in the JSON object string during deserialization. - TriynkoDateTime. But, if you wrap the DateTime in another object, it works. - Brian Rogers