Пример #1
0
        private ServiceResult <HttpRequestMessage> TryCreateHttpRequest(HttpMethod httpMethod, string relativeUrlPattern, IEnumerable <KeyValuePair <string, string> > uriParameters, IEnumerable <KeyValuePair <string, string> > requestHeaders)
        {
            string url = m_baseUrl.TrimEnd('/') + "/" + relativeUrlPattern.TrimStart('/');

            if (uriParameters != null)
            {
                url = GetUrlFromPattern(url, uriParameters);
            }

            var requestMessage = new HttpRequestMessage(httpMethod, url);

            var headersResult = HttpServiceUtility.TryAddHeaders(requestMessage.Headers, requestHeaders);

            if (headersResult.IsFailure)
            {
                return(headersResult.AsFailure());
            }

            return(ServiceResult.Success(requestMessage));
        }
Пример #2
0
        private ServiceResult <HttpRequestMessage> TryCreateHttpRequest(HttpMethod httpMethod, string relativeUriPattern, IEnumerable <KeyValuePair <string, string> > uriParameters, IEnumerable <KeyValuePair <string, string> > requestHeaders)
        {
            string uriText = m_baseUri.AbsoluteUri;

            if (!string.IsNullOrEmpty(relativeUriPattern))
            {
                uriText = uriText.TrimEnd('/') + "/" + relativeUriPattern.TrimStart('/');
            }

            Uri uri = uriParameters != null?GetUriFromPattern(uriText, uriParameters) : new Uri(uriText);

            var requestMessage = new HttpRequestMessage(httpMethod, uri);

            var headersResult = HttpServiceUtility.TryAddHeaders(requestMessage.Headers, requestHeaders);

            if (headersResult.IsFailure)
            {
                return(headersResult.AsFailure());
            }

            return(ServiceResult.Success(requestMessage));
        }
Пример #3
0
        /// <summary>
        /// Attempts to handle a service method.
        /// </summary>
        protected async Task <HttpResponseMessage> TryHandleServiceMethodAsync <TRequest, TResponse>(HttpMethodMapping <TRequest, TResponse> mapping, HttpRequestMessage httpRequest, Func <TRequest, CancellationToken, Task <ServiceResult <TResponse> > > invokeMethodAsync, CancellationToken cancellationToken)
            where TRequest : ServiceDto, new()
            where TResponse : ServiceDto, new()
        {
            if (httpRequest.Method != mapping.HttpMethod)
            {
                return(null);
            }

            var pathParameters = TryMatchHttpRoute(httpRequest.RequestUri, m_rootPath + mapping.Path);

            if (pathParameters == null)
            {
                return(null);
            }

            var context = new ServiceHttpContext();

            ServiceHttpContext.SetContext(httpRequest, context);

            var aspectHttpResponse = await AdaptTask(RequestReceivedAsync(httpRequest, cancellationToken)).ConfigureAwait(true);

            if (aspectHttpResponse != null)
            {
                return(aspectHttpResponse);
            }

            string mediaType = GetResponseMediaType(httpRequest);

            ServiceErrorDto error = null;

            object requestBody = null;

            if (mapping.RequestBodyType != null)
            {
                var requestResult = await AdaptTask(m_contentSerializer.ReadHttpContentAsync(mapping.RequestBodyType, httpRequest.Content, cancellationToken)).ConfigureAwait(true);

                if (requestResult.IsFailure)
                {
                    error = requestResult.Error;
                }
                else
                {
                    requestBody = requestResult.Value;
                }
            }

            TResponse response = null;

            if (error == null)
            {
                var request = mapping.CreateRequest(requestBody);

                var uriParameters = new Dictionary <string, string>();
                foreach (var queryParameter in ParseQueryString(httpRequest.RequestUri.Query))
                {
                    uriParameters[queryParameter.Key] = queryParameter.Value[0];
                }
                foreach (var pathParameter in pathParameters)
                {
                    uriParameters[pathParameter.Key] = pathParameter.Value;
                }
                request = mapping.SetUriParameters(request, uriParameters);
                request = mapping.SetRequestHeaders(request, HttpServiceUtility.CreateDictionaryFromHeaders(httpRequest.Headers));

                context.Request = request;

                var methodResult = await invokeMethodAsync(request, cancellationToken).ConfigureAwait(true);

                if (methodResult.IsFailure)
                {
                    error = methodResult.Error;
                }
                else
                {
                    response = methodResult.Value;
                }

                context.Result = error != null?ServiceResult.Failure(error) : ServiceResult.Success <ServiceDto>(response);
            }

            HttpResponseMessage httpResponse;

            if (error == null)
            {
                var responseMappingGroups = mapping.ResponseMappings
                                            .GroupBy(x => x.MatchesResponse(response))
                                            .Where(x => x.Key != false)
                                            .OrderByDescending(x => x.Key)
                                            .ToList();
                if (responseMappingGroups.Count >= 1 && responseMappingGroups[0].Count() == 1)
                {
                    var responseMapping = responseMappingGroups[0].Single();
                    httpResponse = new HttpResponseMessage(responseMapping.StatusCode);

                    var headersResult = HttpServiceUtility.TryAddHeaders(httpResponse.Headers, mapping.GetResponseHeaders(response));
                    if (headersResult.IsFailure)
                    {
                        throw new InvalidOperationException(headersResult.Error.Message);
                    }

                    if (responseMapping.ResponseBodyType != null)
                    {
                        httpResponse.Content = m_contentSerializer.CreateHttpContent(responseMapping.GetResponseBody(response), mediaType);
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Found {responseMappingGroups.Sum(x => x.Count())} valid HTTP responses for {typeof(TResponse).Name}: {response}");
                }
            }
            else
            {
                var statusCode = error.Code == null ? HttpStatusCode.InternalServerError :
                                 (TryGetCustomHttpStatusCode(error.Code) ?? HttpServiceErrors.TryGetHttpStatusCode(error.Code) ?? HttpStatusCode.InternalServerError);
                httpResponse = new HttpResponseMessage(statusCode);
                if (statusCode != HttpStatusCode.NoContent && statusCode != HttpStatusCode.NotModified)
                {
                    httpResponse.Content = m_contentSerializer.CreateHttpContent(error, mediaType);
                }
            }

            httpResponse.RequestMessage = httpRequest;
            await AdaptTask(ResponseReadyAsync(httpResponse, cancellationToken)).ConfigureAwait(true);

            return(httpResponse);
        }