mgholam / fastJSON

Smallest, fastest polymorphic JSON serializer
https://www.codeproject.com/Articles/159450/fastJSON-Smallest-Fastest-Polymorphic-JSON-Seriali
MIT License
478 stars 148 forks source link

Failed to change type #111

Closed alesrazym closed 4 years ago

alesrazym commented 4 years ago

For some reason, serializing and deserializing generic collection of int or long, eg. List or int[] fails to be deserialized.

fastJSON.deserializer.ChangeType (System.Object value, System.Type conversionType) (at fastJSON/JSON.cs:492)
fastJSON.deserializer.DoParseList (System.Collections.IList parse, System.Type it, System.Collections.IList o) (at fastJSON/JSON.cs:565)
fastJSON.deserializer.RootArray (System.Object parse, System.Type type) (at fastJSON/JSON.cs:575)
fastJSON.deserializer.ToObject (System.String json, System.Type type) (at fastJSON/JSON.cs:440)
fastJSON.deserializer.ToObject[T] (System.String json) (at fastJSON/JSON.cs:380)
fastJSON.JSON.ToObject[T] (System.String json) (at fastJSON/JSON.cs:239)

This happens because int is read back as decimal and cannot be converted to long.

This can be handled with small change to JSON.cs to check for decimal:

private object ChangeType(object value, Type conversionType)
{
    if (conversionType == typeof(int))
    {
        string s = value as string;
        if (s == null)
            if (value is decimal dec)
                return decimal.ToInt32(dec);
            else
                return (int)((long)value);
        else if (_params.AutoConvertStringToNumbers)
            return Helper.CreateInteger(s, 0, s.Length);
        else
            throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
    }
    else if (conversionType == typeof(long))
    {
        string s = value as string;
        if (s == null)
            if (value is decimal dec)
                return decimal.ToInt64(dec);
            else
                return (long)value;
        else if (_params.AutoConvertStringToNumbers)
            return Helper.CreateLong(s, 0, s.Length);
        else
            throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
    }
...

Or did I miss something?

mgholam commented 4 years ago

That is strange, it should be covered in the tests, do you have a sample code for this?

alesrazym commented 4 years ago

Now I see we have some version older then 2.2.6