Azure / azure-functions-eventgrid-extension

EventGrid extension for Azure Functions
MIT License
48 stars 34 forks source link

add support for newtonsoft 9.0+, fix #28 #34

Closed watashiSHUN closed 2 months ago

watashiSHUN commented 6 years ago

add a test case with a function referencing newtonsoft 11

watashiSHUN commented 6 years ago

A more efficient solution would be jobject.ToObject(version11.GetType("Newtonsoft.Json.Linq.JObject"); however, when this is invoked I am getting an exception:

Newtonsoft.Json.JsonSerializationException HResult=0x80131500 Message=Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Newtonsoft.Json.Linq.JToken' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'data.fileUrl', line 8, position 14. Source=Newtonsoft.Json StackTrace: at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer) at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType)

after a quick investigation, here is my theory:

the newtonsoft does something special to deal with ToObject(Linq) https://github.com/JamesNK/Newtonsoft.Json/blob/ce7f283b94c86341036078ed2f4e241b907b816d/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs#L280-L294

Since jobject of newtonsoft.json 11 is not recognized, it will go through the regular code path and it will hit an issue when we have jobject inside another jobject: {content: {}}, the internal {} is of type JToken which unlike JObject does not implement IDictionary. it will be treated as an array (since it implemented IEnumerable) and hence the library will complain that it cannot convert from object to array