You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Nullable DateTime does not deserialize correctly #98
Attempting to deserialise a string containing a date into an object where the field is a Nullable<DateTime> results in a FormatException with the error:
String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider, DateTimeStyles styles)>
at NetJSON.NetJSON.FastStringToDate(String value)
at FailingClassClass.ExtractNullableDateTime(Char* , Int32& )
at FailingClassClass.CreateClassOrDictFailingClass(Char* , Int32& )
at FailingClassClass.ReadFailingClass(String )
at FailingClassClass.Deserialize(String )
at NetJSON.NetJSON.Deserialize[T](String json)
A minimal repro is:
voidMain(){varfailing=newFailingClass{ThisGoesBang=newDateTime(2015,12,25,16,30,00)};varfailStr=NetJSON.NetJSON.Serialize(failing);Console.WriteLine(failStr);varfailResult=NetJSON.NetJSON.Deserialize<FailingClass>(failStr);// Never get past here, we explode with a FormatException Console.WriteLine("FailingClass Field is Correct? - {0}",failing.ThisGoesBang==failResult.ThisGoesBang);}publicclassFailingClass{publicDateTime?ThisGoesBang{get;set;}}
I wrote a simple console app to test out as many common value types as I could think of. The FormatException appears when we use a nullable for:
DateTime
TimeSpan
Guid
long, int, short (and their unsigned variants), float, double, decimal, byte, sbyte, enum and bool are fine.
I've attached a LinqPad script which I used to run the tests: NetJSOn Tests.zip
The exceptions with strings for deserialization for the failed types are:
Type: System.DateTime - Fail. Serialised JSON - {"TestItem":"/Date(14501376000000000)/"}
Exception: System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider, DateTimeStyles styles)
at NetJSON.NetJSON.FastStringToDate(String value)
at TestType1DateTimeClass.ExtractNullableDateTime(Char* , Int32& ) at TestType1DateTimeClass.CreateClassOrDictTestTypeDateTime(Char* , Int32& )
at TestType1DateTimeClass.ReadTestTypeDateTime(String ) at TestType1DateTimeClass.Deserialize(String )
at DeserializeUserQuery+TestType`1[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
at NetJSON.NetJSON.Deserialize(Type type, String value)
at UserQuery.TestSerialisation[T](T value) in query_byzzwm.cs:line 92
Type: System.TimeSpan - Fail. Serialised JSON - {"TestItem":"00:00:00.0001500"}
Exception: System.FormatException: String was not recognized as a valid TimeSpan.
at System.Globalization.TimeSpanParse.TimeSpanResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object > failureMessageFormatArgument, String failureArgumentName)
at System.Globalization.TimeSpanParse.ProcessTerminal_HMS_F_D(TimeSpanRawInfo& raw, TimeSpanStandardStyles style, TimeSpanResult& result)
at System.Globalization.TimeSpanParse.ProcessTerminalState(TimeSpanRawInfo& raw, TimeSpanStandardStyles style, TimeSpanResult& result)
at System.Globalization.TimeSpanParse.TryParseTimeSpan(String input, TimeSpanStandardStyles style, IFormatProvider formatProvider, TimeSpanResult& > result)
at System.Globalization.TimeSpanParse.Parse(String input, IFormatProvider formatProvider)
at TestType1TimeSpanClass.ExtractNullableTimeSpan(Char* , Int32& ) at TestType1TimeSpanClass.CreateClassOrDictTestTypeTimeSpan(Char* , Int32& )
at TestType1TimeSpanClass.ReadTestTypeTimeSpan(String ) at TestType1TimeSpanClass.Deserialize(String )
at DeserializeUserQuery+TestType`1[System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
at NetJSON.NetJSON.Deserialize(Type type, String value)
at UserQuery.TestSerialisation[T](T value) in query_byzzwm.cs:line 92
Type: System.Guid - Fail. Serialised JSON - {"TestItem":"10b5a72b-815f-4e64-90bf-cb250840e989"}
Exception: System.FormatException: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
at System.Guid.GuidResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument, String > failureArgumentName, Exception innerException)
at System.Guid.TryParseGuidWithDashes(String guidString, GuidResult& result)
at System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)
at System.Guid..ctor(String g)
at TestType1GuidClass.ExtractNullableGuid(Char* , Int32& ) at TestType1GuidClass.CreateClassOrDictTestTypeGuid(Char* , Int32& )
at TestType1GuidClass.ReadTestTypeGuid(String ) at TestType1GuidClass.Deserialize(String )
at DeserializeUserQuery+TestType`1[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
at NetJSON.NetJSON.Deserialize(Type type, String value)
at UserQuery.TestSerialisation[T](T value) in query_byzzwm.cs:line 92
What is interesting is that all the values shows are actually valid for their types. I wonder if it is passing additional text/string into the method when ever they are nullable such as quotes. I will look into and get back to you thanks. Thanks for the sample tests :)
The root of the bug seems to be that the string that is passed to the constructor for Guid, DateTime and TimeSpan still contains a leading and trailing quote. To take Guid as an example, the string passed into FastStringToGuid should be: "10b5a72b-815f-4e64-90bf-cb250840e989" but is actually "\"10b5a72b-815f-4e64-90bf-cb250840e989\""
Activity
rpgmaker commentedon Dec 17, 2015
Thanks for the find. Could you try to do similar with nullable long.
Thanks,
LeapingGorilla commentedon Dec 17, 2015
I wrote a simple console app to test out as many common value types as I could think of. The
FormatExceptionappears when we use a nullable for:DateTimeTimeSpanGuidlong,int,short(and their unsigned variants),float,double,decimal,byte,sbyte,enumandboolare fine.I've attached a LinqPad script which I used to run the tests: NetJSOn Tests.zip
The exceptions with strings for deserialization for the failed types are:
rpgmaker commentedon Dec 18, 2015
What is interesting is that all the values shows are actually valid for their types. I wonder if it is passing additional text/string into the method when ever they are nullable such as quotes. I will look into and get back to you thanks. Thanks for the sample tests :)
Thanks
LeapingGorilla commentedon Dec 18, 2015
The root of the bug seems to be that the string that is passed to the constructor for Guid, DateTime and TimeSpan still contains a leading and trailing quote. To take Guid as an example, the string passed into
FastStringToGuidshould be:"10b5a72b-815f-4e64-90bf-cb250840e989"but is actually"\"10b5a72b-815f-4e64-90bf-cb250840e989\""rpgmaker commentedon Dec 18, 2015
Can you please confirm if it is working?
Thanks,
LeapingGorilla commentedon Dec 18, 2015
Confirmed as fixed in NuGet package 1.0.15.5. Nice work