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

IReadOnlyList<T> not deserialized #473

Open
pandabytes opened this issue Nov 2, 2023 · 0 comments
Open

IReadOnlyList<T> not deserialized #473

pandabytes opened this issue Nov 2, 2023 · 0 comments

Comments

@pandabytes
Copy link

pandabytes commented Nov 2, 2023

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());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant