Client fails to handle IDictionary implementations
cdavernas opened this issue · 0 comments
cdavernas commented
What happens?
The OData client fails to properly handle non-default implementation of the IDictionary interface
What do you expect to happen?
The OData client to properly handle non-default implementation of the IDictionary interface
How to reproduce?
- Create a new dictionary implementation, such as the following:
public class NameValueCollection<T>
: IDictionary<string, T>, ICollection
{
//...
public NameValueCollection()
{
//...
}
public NameValueCollection(IEnumerable<KeyValuePair<string, T>> source)
{
//...
}
//..
}
- Add a NameValueCollection property to one of the models exposed on OData:
public class Book
{
//...
public string Title { get; set;}
public string Author { get; set; }
public NameValueCollection<string> Metadata { get; set; }
//...
}
- Make an OData request to list books via the Simple.OData.Client
Additional information
Stack trace:
Simple.OData.Client.Extensions.ConstructorNotFoundException: Could not find a constructor for type 'NameValueCollection`1' with the following argument types: IEnumerable`1
at Simple.OData.Client.Extensions.ExpressionActivator.CreateActivator(Type type, Type[] parameters)
at Simple.OData.Client.Extensions.DictionaryExtensions.<>c__DisplayClass16_0.<ConvertCollection>b__0(Tuple`2 t)
at System.Collections.Concurrent.ConcurrentDictionary`2[[System.Tuple`2[[System.Type, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Type, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Simple.OData.Client.Extensions.ActivatorDelegate, Simple.OData.Client.Core, Version=5.26.0.0, Culture=neutral, PublicKeyToken=58885f4495efc1ae]].GetOrAdd(Tuple`2 key, Func`2 valueFactory)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertCollection(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertValue(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ToObject(IDictionary`2 source, ITypeCache typeCache, Type type, Boolean dynamicObject)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertSingle(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertCollection(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertValue(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ToObject(IDictionary`2 source, ITypeCache typeCache, Type type, Boolean dynamicObject)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertSingle(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertCollection(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ConvertValue(Type type, ITypeCache typeCache, Object itemValue)
at Simple.OData.Client.Extensions.DictionaryExtensions.ToObject(IDictionary`2 source, ITypeCache typeCache, Type type, Boolean dynamicObject)
at Simple.OData.Client.Extensions.DictionaryExtensions.ToObject[V1Correlation](IDictionary`2 source, ITypeCache typeCache, Boolean dynamicObject)
at Simple.OData.Client.FluentClientBase`2[[Synapse.Integration.Models.V1Correlation, Synapse.Integration, Version=0.1.25.0, Culture=neutral, PublicKeyToken=null],[Simple.OData.Client.IBoundClient`1[[Synapse.Integration.Models.V1Correlation, Synapse.Integration, Version=0.1.25.0, Culture=neutral, PublicKeyToken=null]], Simple.OData.Client.Core, Version=5.26.0.0, Culture=neutral, PublicKeyToken=58885f4495efc1ae]].ConvertResult(IDictionary`2 result, String dynamicPropertiesContainerName)
at Simple.OData.Client.FluentClientBase`2.<>c__DisplayClass97_0[[Synapse.Integration.Models.V1Correlation, Synapse.Integration, Version=0.1.25.0, Culture=neutral, PublicKeyToken=null],[Simple.OData.Client.IBoundClient`1[[Synapse.Integration.Models.V1Correlation, Synapse.Integration, Version=0.1.25.0, Culture=neutral, PublicKeyToken=null]], Simple.OData.Client.Core, Version=5.26.0.0, Culture=neutral, PublicKeyToken=58885f4495efc1ae]].<FilterAndTypeColumnsAsync>b__0(IDictionary`2 z)
at System.Linq.Utilities.<>c__DisplayClass2_0`3[[Simple.OData.Client.AnnotatedEntry, Simple.OData.Client.Core, Version=5.26.0.0, Culture=neutral, PublicKeyToken=58885f4495efc1ae],[System.Collections.Generic.IDictionary`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Synapse.Integration.Models.V1Correlation, Synapse.Integration, Version=0.1.25.0, Culture=neutral, PublicKeyToken=null]].<CombineSelectors>b__0(AnnotatedEntry x)
Note to implementers
The bug is due to an improper check in the DictionaryExtensions: I believe you should test there if the type passed as argument is an IDictionary
implementation, in which case the element type should be KeyValuePair<T1, T2>
instead of just T1.