graphql-client: PostAsync method does not work in WebGL due to System.Reflection.Emit reference

I am trying to use graphql-client to build WebGL Client which communicates with graphql server.

Currently WebGL in Unity does not support System.Reflection.Emit.

Call from line https://github.com/graphql-dotnet/graphql-client/blob/9511133bc922af7ef0cb1f760b7885a9243275e2/src/GraphQL.Client.Http/Internal/GraphQLHttpHandler.cs#L65 is using Newtonsoft.Json which internally use not supported functionality from System.Reflection.Emit.

Here is Stack trace:

System.NotSupportedException: System.Reflection.Emit.DynamicMethod::.ctor
UnityLoader.js:1043   at System.Reflection.Emit.DynamicMethod..ctor (System.String name, System.Type returnType, System.Type[] parameterTypes, System.Type owner, System.Boolean skipVisibility) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Utilities.DynamicReflectionDelegateFactory.CreateDynamicMethod (System.String name, System.Type returnType, System.Type[] parameterTypes, System.Type owner) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Utilities.DynamicReflectionDelegateFactory.CreateDefaultConstructor[T] (System.Type type) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.DefaultContractResolver.GetDefaultCreator (System.Type createdType) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.DefaultContractResolver.InitializeContract (Newtonsoft.Json.Serialization.JsonContract contract) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract (System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract (System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolveContract (System.Type type) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.GetContractSafe (System.Object value) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.JsonSerializer.SerializeInternal (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.JsonSerializer.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializer jsonSerializer) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at GraphQL.Client.GraphQLClient+<PostAsync>d__22.MoveNext () [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[TResult].Start[TStateMachine] (TStateMachine& stateMachine) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at GraphQL.Client.GraphQLClient.PostAsync (GraphQL.Common.Request.GraphQLRequest request, System.Threading.CancellationToken cancellationToken) [0x00000] in <00000000000000000000000000000000>:0 
UnityLoader.js:1043   at GraphQL.Client.GraphQLClient.PostAsync (GraphQL.Common.Request.GraphQLRequest request) [0x00000] in <00000000000000000000000000000000>:0 

Would it be possible to use another serialization/deserialization package, which would replace Newtonsoft.Json, which functionality is not supported in WebGL? (Going to try other one)

Maybe in the future there could be option to replace hardcoded Newtonsoft.json

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 29 (17 by maintainers)

Most upvoted comments

Newtonsoft.Json has DynamicCodeGeneration setting which was evaluated as true (perhaps by mistake, but nevertheless it is clear that the author of the package provided for several modes of operation and tried to provide an optimized default path).

You can use custom contract resolver and override DefaultContractResolver:

public class MyResolver : DefaultContractResolver
{
  protected override IValueProvider CreateMemberValueProvider(MemberInfo member)
  {
    return new ReflectionValueProvider(member);
  }
}

Then set this resolver to json serializer settings into graphql client options.

Maybe in the future there could be option to replace hardcoded Newtonsoft.json

It is a long way, but many follow it include ASP.NET Core Team.

@deinok, please, consider to move Newtonsoft.Json dependency out of core graphql client code.

Also, I would still recommend you to post an issue for this problem in NewtonSoft.Json repo. The type has a constructor, but the serializer for some reason does not find it.

@ondrej-mikulas @sungam3r I have the same issue in trying to build for the Lumin platform (il2cpp) in Unity where dynamics is not supported and i get the same errors.

What is the workaround for this, that would be extremely helpful. I dont exactly understand the DefaultContractResolver solution above or if there is a way to use another parser instead of newton json. Any help would be appreciated! Thanks, Sidhant