Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TargetParameterCountException deserializing Generic List (.NET 2.0) #37

Open
hackedd opened this issue Sep 9, 2013 · 3 comments
Open
Labels

Comments

@hackedd
Copy link

hackedd commented Sep 9, 2013

When deserializing a Generic List (as in the example below), SimpleJson throws TargetParameterCountException when the Target framework for the Project is set to .NET 2.0.

using SimpleJson;

class Program
{
    public class Container
    {
        public List<int> items;
    }

    static void Main(string[] args)
    {
        string json = "{ \"items\": [ 1, 2, 3 ] }";
        Container obj;

        obj = SimpleJson.SimpleJson.DeserializeObject<Container>(json);
        Console.WriteLine(obj.items.Count);
    }
}

I think the problem is caused by ContructorDelegateFactory in SimpleJson.PocoJsonSerializerStrategy which calls ReflectionUtils.GetContructor to get a constructor for the generic List with no arguments. The constructor is later invoked (by DeserializeObject) with the number of items in the list as first and only argument.

If I change the code in ContructorDelegateFactory to account for Lists, it seems to work:

bool isArrayOrList = key.IsArray || ReflectionUtils.IsTypeGenericeCollectionInterface(key) || ReflectionUtils.IsAssignableFrom(typeof(IList), key);
return ReflectionUtils.GetContructor(key, isArrayOrList ? ArrayConstructorParameterTypes : EmptyTypes);
@prabirshrestha
Copy link
Member

This bug seems to affects .net 4.0 too.

Seems like we have tests for int[] and List<CustomObject> but not for List<int> when T is of primitive types.
https://github.com/facebook-csharp-sdk/simple-json/blob/master/src/SimpleJson.Tests/PocoDeserializerTests/ArrayTests.cs
https://github.com/facebook-csharp-sdk/simple-json/blob/master/src/SimpleJson.Tests/PocoDeserializerTests/ListOfPocoDeserializeTests.cs

Could you create a unit test and send a PR.

Thanks.

@Terricide
Copy link

I fixed the issue for my project by modifying the code below. Adding the following to the GetConstructorInfo

            if (typeof(IList).IsAssignableFrom(type) && argsType.Length == 0)
            {
                argsType = new Type[] { typeof(int) };
            }



        public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType)
        {
            IEnumerable<ConstructorInfo> constructorInfos = GetConstructors(type);
            int i;
            bool matches;

            if (typeof(IList).IsAssignableFrom(type) && argsType.Length == 0)
            {
                argsType = new Type[] { typeof(int) };
            }
            foreach (ConstructorInfo constructorInfo in constructorInfos)
            {
                ParameterInfo[] parameters = constructorInfo.GetParameters();
                if (argsType.Length != parameters.Length)
                    continue;

                i = 0;
                matches = true;
                foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters())
                {
                    if (parameterInfo.ParameterType != argsType[i])
                    {
                        matches = false;
                        break;
                    }
                }

                if (matches)
                    return constructorInfo;
            }

            return null;
        }

@prabirshrestha
Copy link
Member

@Terricide can u send a PR. You will first need to send a PR to the reflection-utils project. https://github.com/facebook-csharp-sdk/reflection-utils

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants