public Task <GraphQLRequestDeserializationResult> DeserializeFromJsonBodyAsync(HttpRequest httpRequest, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); // Do not explicitly or implicitly (via using, etc.) call dispose because StreamReader will dispose inner stream. // This leads to the inability to use the stream further by other consumers/middlewares of the request processing // pipeline. In fact, it is absolutely not dangerous not to dispose StreamReader as it does not perform any useful // work except for the disposing inner stream. var reader = new StreamReader(httpRequest.Body); var result = new GraphQLRequestDeserializationResult { IsSuccessful = true }; using (var jsonReader = new JsonTextReader(reader) { CloseInput = false }) { int firstChar = reader.Peek(); cancellationToken.ThrowIfCancellationRequested(); switch (firstChar) { case '{': result.Single = ToGraphQLRequest(_serializer.Deserialize <InternalGraphQLRequest>(jsonReader)); break; case '[': result.Batch = _serializer.Deserialize <InternalGraphQLRequest[]>(jsonReader) .Select(ToGraphQLRequest) .ToArray(); break; default: result.IsSuccessful = false; break; } } return(Task.FromResult(result)); }
public async Task <GraphQLRequestDeserializationResult> DeserializeFromJsonBodyAsync(HttpRequest httpRequest, CancellationToken cancellationToken = default) { var bodyReader = httpRequest.BodyReader; JsonTokenType jsonTokenType; try { jsonTokenType = await PeekJsonTokenTypeAsync(bodyReader, cancellationToken); } catch (JsonException) { // Invalid request content, assign None so it falls through to IsSuccessful = false jsonTokenType = JsonTokenType.None; } cancellationToken.ThrowIfCancellationRequested(); var result = new GraphQLRequestDeserializationResult { IsSuccessful = true }; switch (jsonTokenType) { case JsonTokenType.StartObject: result.Single = ToGraphQLRequest( await JsonSerializer.DeserializeAsync <InternalGraphQLRequest>(bodyReader.AsStream(), _serializerOptions, cancellationToken)); return(result); case JsonTokenType.StartArray: result.Batch = (await JsonSerializer.DeserializeAsync <InternalGraphQLRequest[]>(bodyReader.AsStream(), _serializerOptions, cancellationToken)) .Select(ToGraphQLRequest) .ToArray(); return(result); default: result.IsSuccessful = false; return(result); } }