graphql.net-core-3.1graphql-playground

.Net core 3.1 + GraphQL ==> "error": "Unexpected end of JSON input"


I developed a .net core 3.1 web API and I've added GraphQL and PlayGround to it. When I try to start the Playground I encountered this error that bored me. I googled too many times and I have read many articles and forums about it and I've tried their suggested ways but still, the problem exists. Also, I should say I haven't this problem with .net core 2.2.

I decided to simplify my solution and remove the extra foliage of my project and upload it to you that you can help me. The simplified version of that project I'm currently working on it is available here on google drive.
Also, I found a solution with .net core 3.1 that hasn't this problem but still, I can't find my mistake(s). I've uploaded this correct solution here.

In this simplified version I didn't connect to the database and didn't add any related of its packages to the project. I'm returning in-memory data in this simplified version instead of contacting the database.

This is the picture of the error that I'm facing: enter image description here

And The .csproj file of the simplified project is like below:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>NetCore3._1GraphQL</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="graphiql" Version="1.2.0" />
    <PackageReference Include="GraphQL" Version="3.0.0-preview-1352" />
    <PackageReference Include="GraphQL.Server.Ui.Playground" Version="3.4.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.1" />
    <PackageReference Include="RandomNameGeneratorLibrary" Version="1.2.2" />
  </ItemGroup>

</Project>

Solution

  • Depending on the simplified and erroneous project, afaict, it is configured with a routing which maps /graphql endpoint to a controller but does not contain a matching controller. So, the server returns 404 response and graphql playground produces error message. Adding a controller (or a middleware) made it work.

    Below are the changes to the simplified and erroneous project that made it work:

    1. Add an api controller matching /graphql routing.
    // GraphqlController.cs
    // using statements are omitted
    namespace NetCore3._1GraphQL.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class GraphqlController : ControllerBase
        {
            private readonly IServiceProvider _provider; 
            private readonly IDocumentExecuter _executer;
            private readonly IDataLoaderContextAccessor _loader;
    
            public GraphqlController(
                IDocumentExecuter executer,
                IServiceProvider provider, 
                IDataLoaderContextAccessor loader)
            {
                _executer = executer;
                _provider = provider;
                _loader = loader;
            }
    
            [HttpPost]
            public async Task<IActionResult> Post([FromBody] GraphQLRequest graphQLRequest)
            {
                if (graphQLRequest == null)
                {
                    throw new ArgumentNullException(nameof(graphQLRequest));
                }
    
                var _query = graphQLRequest.Query;
                var _inputs = graphQLRequest.Variables?.ToObject<Inputs>();
                var _options = new ExecutionOptions
                {
                    Schema = new GraphQLSchema(_provider)
                    {
                        Query = new GraphQLQuery(_loader),
                    },
                    Query = _query,
                    Inputs = _inputs,
                    FieldNameConverter = new PascalCaseFieldNameConverter()
                };
    
                try
                {
                    var result = await _executer.ExecuteAsync(_options).ConfigureAwait(false);
    
                    if (result.Errors?.Count > 0)
                    {
                        return BadRequest(result);
                    }
    
                    return Ok(result);
                }
                catch (Exception ex)
                {
                    return BadRequest(ex);
                }
            }
        }
    }
    
    
    1. Uncomment the line public JObject Variables { get; set; } in BaseGraphQLQuery.cs.

    2. BaseGraphQLQuery class is an implementation of a GraphQL request, not a GraphQL query. Rename it as GraphQLRequest or change the parameter name in the controller's post action to BaseGraphQLQuery.

    A successfull query with Graphql Playground app.