private async Task <IMessage> CreateMessage(HttpRequest request)
        {
            IMessage?requestMessage;

            if (_bodyDescriptor != null)
            {
                if (request.ContentType == null ||
                    !request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("Request content-type of application/json is required.");
                }

                if (!request.Body.CanSeek)
                {
                    // JsonParser does synchronous reads. In order to avoid blocking on the stream, we asynchronously
                    // read everything into a buffer, and then seek back to the beginning.
                    request.EnableBuffering();
                    Debug.Assert(request.Body.CanSeek);

                    await request.Body.DrainAsync(CancellationToken.None);

                    request.Body.Seek(0L, SeekOrigin.Begin);
                }

                var encoding = RequestEncoding.SelectCharacterEncoding(request);
                // TODO: Handle unsupported encoding

                using (var requestReader = new HttpRequestStreamReader(request.Body, encoding))
                {
                    if (_bodyDescriptorRepeated)
                    {
                        var containingMessage = ParseRepeatedContent(requestReader);

                        if (_resolvedBodyFieldDescriptors !.Count > 0)
                        {
                            requestMessage = (IMessage)Activator.CreateInstance <TRequest>();
                            ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, _resolvedBodyFieldDescriptors, containingMessage);
                        }
                        else
                        {
                            requestMessage = containingMessage;
                        }
                    }
                    else
                    {
                        var bodyContent = JsonParser.Default.Parse(requestReader, _bodyDescriptor);

                        if (_bodyFieldDescriptors != null)
                        {
                            requestMessage = (IMessage)Activator.CreateInstance <TRequest>();
                            ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, _bodyFieldDescriptors, bodyContent);
                        }
                        else
                        {
                            requestMessage = bodyContent;
                        }
                    }
                }
        private async Task <IMessage> CreateMessage(HttpRequest request)
        {
            IMessage?requestMessage;

            if (_bodyDescriptor != null)
            {
                if (request.ContentType == null ||
                    !request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("Request content-type of application/json is required.");
                }

                if (!request.Body.CanSeek)
                {
                    // JsonParser does synchronous reads. In order to avoid blocking on the stream, we asynchronously
                    // read everything into a buffer, and then seek back to the beginning.
                    request.EnableBuffering();
                    Debug.Assert(request.Body.CanSeek);

                    await request.Body.DrainAsync(CancellationToken.None);

                    request.Body.Seek(0L, SeekOrigin.Begin);
                }

                var encoding = RequestEncoding.SelectCharacterEncoding(request);
                // TODO: Handle unsupported encoding

                IMessage bodyContent;
                using (var requestReader = new HttpRequestStreamReader(request.Body, encoding))
                {
                    bodyContent = JsonParser.Default.Parse(requestReader, _bodyDescriptor);
                }

                if (_bodyFieldDescriptor != null)
                {
                    requestMessage = (IMessage)Activator.CreateInstance <TRequest>();
                    _bodyFieldDescriptor.Accessor.SetValue(requestMessage, bodyContent);
                }
                else
                {
                    requestMessage = bodyContent;
                }
            }
            else
            {
                requestMessage = (IMessage)Activator.CreateInstance <TRequest>();
            }

            foreach (var parameterDescriptor in _routeParameterDescriptors)
            {
                var routeValue = request.RouteValues[parameterDescriptor.Key];
                if (routeValue != null)
                {
                    ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, parameterDescriptor.Value, routeValue);
                }
            }

            foreach (var item in request.Query)
            {
                if (CanBindQueryStringVariable(item.Key))
                {
                    if (!_queryParameterDescriptors.TryGetValue(item.Key, out var pathDescriptors))
                    {
                        if (ServiceDescriptorHelpers.TryResolveDescriptors(requestMessage.Descriptor, item.Key, out pathDescriptors))
                        {
                            _queryParameterDescriptors[item.Key] = pathDescriptors;
                        }
                    }

                    if (pathDescriptors != null)
                    {
                        object value = item.Value.Count == 1 ? (object)item.Value[0] : item.Value;
                        ServiceDescriptorHelpers.RecursiveSetValue(requestMessage, pathDescriptors, value);
                    }
                }
            }

            return(requestMessage);
        }