Skip to content

IReadOnlyList<T> not deserialized #473

@pandabytes

Description

@pandabytes

Hello. I'm curious as to why IReadOnlyList and other interfaces that implement IEnumerable (such as IReadOnlyCollection) do not get deserialized correctly. I see this code here we exactly check for type List and IEnumerable.

else if (genericTypeDefinition == typeof(List<>))
{
instance = BuildList(context, type, element.Children(), typeMappings, nestingLevel + 1);
}
else if (genericTypeDefinition == typeof(IEnumerable<>))
{
instance = BuildIEnumerable(context, type, element.Children(), typeMappings, nestingLevel + 1);
}

Example

public class Person
{
  public IReadOnlyList<string> Names { get; set; }
}

This is the error I get when I try to deserialize to Person from neo4j.

 ---> System.MissingMethodException: Cannot dynamically create an instance of type 'System.Collections.Generic.IReadOnlyList`1[System.String]'. Reason: Cannot create an instance of an interface.
         at System.RuntimeType.ActivatorCache..ctor(RuntimeType rt)
         at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
         at Neo4jClient.Serialization.CommonDeserializerMethods.CreateAndMap(DeserializationContext context, Type type, JToken element, IEnumerable`1 typeMappings, Int32 nestingLevel)
         at Neo4jClient.Serialization.CommonDeserializerMethods.CoerceValue(DeserializationContext context, PropertyInfo propertyInfo, JToken value, IEnumerable`1 typeMappings, Int32 nestingLevel)
         at Neo4jClient.Serialization.CommonDeserializerMethods.SetPropertyValue(DeserializationContext context, Object targetObject, PropertyInfo propertyInfo, JToken value, IEnumerable`1 typeMappings, Int32 nestingLevel)
         at Neo4jClient.Serialization.CommonDeserializerMethods.Map(DeserializationContext context, Object targetObject, JToken parentJsonToken, IEnumerable`1 typeMappings, Int32 nestingLevel)
         at Neo4jClient.Serialization.CommonDeserializerMethods.CreateAndMap(DeserializationContext context, Type type, JToken element, IEnumerable`1 typeMappings, Int32 nestingLevel)
         at Neo4jClient.Serialization.CypherJsonDeserializer`1.<>c__DisplayClass20_0.<ParseInSingleColumnMode>b__3(JArray row)
         at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToArray()
         at Neo4jClient.Serialization.CypherJsonDeserializer`1.Deserialize(String content, Boolean isHttp)

Workaround

My current workaround is to create a custom JsonConverter, however, it does not work when I use it with [JsonConverter] attribute. It does work if I add the converter to the client. This is what I mean.

public class Person
{
  // This does not work. Get the same error above.
  // Do you have any idea why this doesn't work?
  [JsonConverter(typeof(IReadOnlyListJsonConverter))]
  public IReadOnlyList<string> Names { get; set; }
}

// This DOES work
var boltClient = new BoltGraphClient(driver);
boltClient.JsonConverters.Add(new IReadOnlyListJsonConverter());

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions