private ServiceResult <T> Execute <T>(ServiceDto request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (m_testInfo == null)
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest("Facility test name is missing; set the FacilityTest HTTP header.")));
            }

            string uncapitalize(string value) => value.Substring(0, 1).ToLowerInvariant() + value.Substring(1);

            string methodName = uncapitalize(request.GetType().Name.Substring(0, request.GetType().Name.Length - "RequestDto".Length));

            if (methodName != m_testInfo.Method)
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Unexpected method name for test {m_testInfo.Test}. expected={m_testInfo.Method} actual={methodName}")));
            }

            var actualRequest = (JObject)ServiceJsonUtility.ToJToken(request);

            if (!JToken.DeepEquals(m_testInfo.Request, actualRequest))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Request did not match for test {m_testInfo.Test}. expected={ServiceJsonUtility.ToJson(m_testInfo.Request)} actual={ServiceJsonUtility.ToJson(actualRequest)}")));
            }

            if (m_testInfo.Error != null)
            {
                var error          = ServiceJsonUtility.FromJToken <ServiceErrorDto>(m_testInfo.Error);
                var errorRoundTrip = ServiceJsonUtility.ToJToken(error);
                if (!JToken.DeepEquals(m_testInfo.Error, errorRoundTrip))
                {
                    return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Error round trip failed for test {m_testInfo.Test}. expected={ServiceJsonUtility.ToJson(m_testInfo.Error)} actual={ServiceJsonUtility.ToJson(errorRoundTrip)}")));
                }
                return(ServiceResult.Failure(error));
            }
            else
            {
                var response          = ServiceJsonUtility.FromJToken <T>(m_testInfo.Response);
                var responseRoundTrip = ServiceJsonUtility.ToJToken(response);
                if (!JToken.DeepEquals(m_testInfo.Response, responseRoundTrip))
                {
                    return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Response round trip failed for test {m_testInfo.Test}. expected={ServiceJsonUtility.ToJson(m_testInfo.Response)} actual={ServiceJsonUtility.ToJson(responseRoundTrip)}")));
                }
                return(ServiceResult.Success(response));
            }
        }
    private ServiceResult <T> Execute <T>(ServiceDto request)
    {
        if (request == null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        var methodName          = Uncapitalize(request.GetType().Name.Substring(0, request.GetType().Name.Length - "RequestDto".Length));
        var testsWithMethodName = m_tests.Where(x => x.Method == methodName).ToList();

        if (testsWithMethodName.Count == 0)
        {
            return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"No tests found for method {methodName}.")));
        }

        var actualRequest            = m_jsonSerializer.ToServiceObject(request);
        var testsWithMatchingRequest = testsWithMethodName.Where(x => ServiceObjectUtility.DeepEquals(x.Request, actualRequest)).ToList();

        if (testsWithMatchingRequest.Count != 1)
        {
            return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest(
                                             $"{testsWithMatchingRequest.Count} of {testsWithMethodName.Count} tests for method {methodName} matched request: " +
                                             $"{m_jsonSerializer.ToJson(actualRequest)} ({string.Join(", ", testsWithMethodName.Select(x => m_jsonSerializer.ToJson(x.Request)))})")));
        }
        var testInfo = testsWithMatchingRequest[0];

        if (testInfo.Error != null)
        {
            var error          = m_jsonSerializer.FromServiceObject <ServiceErrorDto>(testInfo.Error);
            var errorRoundTrip = m_jsonSerializer.ToServiceObject(error);
            if (!ServiceObjectUtility.DeepEquals(testInfo.Error, errorRoundTrip))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Error round trip failed for test {testInfo.Test}. expected={m_jsonSerializer.ToJson(testInfo.Error)} actual={m_jsonSerializer.ToJson(errorRoundTrip)}")));
            }
            return(ServiceResult.Failure(error));
        }
        else
        {
            var response          = m_jsonSerializer.FromServiceObject <T>(testInfo.Response !);
            var responseRoundTrip = m_jsonSerializer.ToServiceObject(response);
            if (!ServiceObjectUtility.DeepEquals(testInfo.Response, responseRoundTrip))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Response round trip failed for test {testInfo.Test}. expected={m_jsonSerializer.ToJson(testInfo.Response)} actual={m_jsonSerializer.ToJson(responseRoundTrip)}")));
            }
            return(ServiceResult.Success(response));
        }
    }
Пример #3
0
        public async Task <IActionResult> GenerateZip([FromForm] string definitionName, [FromForm] string definitionText, [FromForm] string generatorName, CancellationToken cancellationToken)
        {
            var request = new GenerateRequestDto
            {
                Definition = new NamedTextDto
                {
                    Name = definitionName,
                    Text = definitionText,
                },
                Generator = new GeneratorDto
                {
                    Name = generatorName,
                },
            };

            var result = await m_api.GenerateAsync(request, cancellationToken).ConfigureAwait(true);

            if (result.IsFailure)
            {
                return(CreateActionResultFromError(result.Error));
            }

            var response = result.Value;
            var failure  = response.Failure;

            if (failure != null)
            {
                return(CreateActionResultFromError(ServiceErrors.CreateInvalidRequest($"({failure.Line},{failure.Column}): {failure.Message}")));
            }

            return(new FileCallbackResult("application/zip", async(outputStream, _) =>
            {
                using (var zipArchive = new ZipArchive(new WriteOnlyStreamWrapper(outputStream), ZipArchiveMode.Create))
                {
                    foreach (var namedText in response.Output)
                    {
                        var zipEntry = zipArchive.CreateEntry(namedText.Name);
                        using (var zipStream = zipEntry.Open())
                            using (var writer = new StreamWriter(zipStream))
                                await writer.WriteAsync(namedText.Text).ConfigureAwait(false);
                    }
                }
            })
            {
                FileDownloadName = $"{request.Generator.Name}.zip"
            });
        }
Пример #4
0
        public async Task <ServiceResult <SetPreferenceResponseDto> > SetPreferenceAsync(SetPreferenceRequestDto request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (string.IsNullOrEmpty(request.Key))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest("Missing preference key.")));
            }

            await m_repository.SetPreferenceAsync(request.Key, request.Value, cancellationToken).ConfigureAwait(false);

            return(ServiceResult.Success(new SetPreferenceResponseDto {
                Value = request.Value
            }));
        }
Пример #5
0
        public async Task <ServiceResult <GetPreferenceResponseDto> > GetPreferenceAsync(GetPreferenceRequestDto request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (string.IsNullOrEmpty(request.Key))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest("Missing preference key.")));
            }

            var value = await m_repository.TryGetPreferenceAsync(request.Key, cancellationToken).ConfigureAwait(false);

            if (value == null)
            {
                return(ServiceResult.Failure(ServiceErrors.CreateNotFound("Preference key not found.")));
            }

            return(ServiceResult.Success(new GetPreferenceResponseDto {
                Value = value
            }));
        }
    /// <summary>
    /// Validates requests and responses.
    /// </summary>
    public static ServiceDelegator Validate(object inner)
    {
        if (inner is null)
        {
            throw new ArgumentNullException(nameof(inner));
        }

        return(async(method, request, cancellationToken) =>
        {
            if (!request.Validate(out var requestErrorMessage))
            {
                return ServiceResult.Failure(ServiceErrors.CreateInvalidRequest(requestErrorMessage));
            }

            var response = await method.InvokeAsync(inner, request, cancellationToken).ConfigureAwait(false);

            if (!response.Validate(out var responseErrorMessage))
            {
                return ServiceResult.Failure(ServiceErrors.CreateInvalidResponse(responseErrorMessage));
            }

            return response;
        });
    }
    /// <summary>
    /// Sends an HTTP request and processes the response.
    /// </summary>
    protected async Task <ServiceResult <TResponse> > TrySendRequestAsync <TRequest, TResponse>(HttpMethodMapping <TRequest, TResponse> mapping, TRequest request, CancellationToken cancellationToken)
        where TRequest : ServiceDto, new()
        where TResponse : ServiceDto, new()
    {
        if (mapping == null)
        {
            throw new ArgumentNullException(nameof(mapping));
        }
        if (request == null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        try
        {
            // validate the request DTO
            if (!m_skipRequestValidation && !request.Validate(out var requestErrorMessage))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest(requestErrorMessage)));
            }

            // make sure the request DTO doesn't violate any HTTP constraints
            var requestValidation = mapping.ValidateRequest(request);
            if (requestValidation.IsFailure)
            {
                return(requestValidation.ToFailure());
            }

            // create the HTTP request with the right method, path, query string, and headers
            var requestHeaders    = mapping.GetRequestHeaders(request);
            var httpRequestResult = TryCreateHttpRequest(mapping.HttpMethod, mapping.Path, mapping.GetUriParameters(request), requestHeaders);
            if (httpRequestResult.IsFailure)
            {
                return(httpRequestResult.ToFailure());
            }

            // create the request body if necessary
            using var httpRequest = httpRequestResult.Value;
            var requestBody = mapping.GetRequestBody(request);
            if (requestBody != null)
            {
                var contentType = mapping.RequestBodyContentType ?? requestHeaders?.GetContentType();
                httpRequest.Content = GetHttpContentSerializer(requestBody.GetType()).CreateHttpContent(requestBody, contentType);
                if (m_disableChunkedTransfer)
                {
                    await httpRequest.Content.LoadIntoBufferAsync().ConfigureAwait(false);
                }
            }

            // send the HTTP request and get the HTTP response
            using var httpResponse = await SendRequestAsync(httpRequest, request, cancellationToken).ConfigureAwait(false);

            // find the response mapping for the status code
            var statusCode      = httpResponse.StatusCode;
            var responseMapping = mapping.ResponseMappings.FirstOrDefault(x => x.StatusCode == statusCode);

            // fail if no response mapping can be found for the status code
            if (responseMapping == null)
            {
                return(ServiceResult.Failure(await CreateErrorFromHttpResponseAsync(httpResponse, cancellationToken).ConfigureAwait(false)));
            }

            // read the response body if necessary
            object?responseBody = null;
            if (responseMapping.ResponseBodyType != null)
            {
                var serializer     = GetHttpContentSerializer(responseMapping.ResponseBodyType);
                var responseResult = await serializer.ReadHttpContentAsync(
                    responseMapping.ResponseBodyType, httpResponse.Content, cancellationToken).ConfigureAwait(false);

                if (responseResult.IsFailure)
                {
                    var error = responseResult.Error !;
                    error.Code = ServiceErrors.InvalidResponse;
                    return(ServiceResult.Failure(error));
                }
                responseBody = responseResult.Value;
            }

            // create the response DTO
            var response = responseMapping.CreateResponse(responseBody);
            response = mapping.SetResponseHeaders(response, HttpServiceUtility.CreateDictionaryFromHeaders(httpResponse.Headers, httpResponse.Content.Headers) !);

            // validate the response DTO
            if (!m_skipResponseValidation && !response.Validate(out var responseErrorMessage))
            {
                return(ServiceResult.Failure(ServiceErrors.CreateInvalidResponse(responseErrorMessage)));
            }

            return(ServiceResult.Success(response));
        }
        catch (OperationCanceledException) when(!cancellationToken.IsCancellationRequested)
        {
            // HttpClient timeout
            return(ServiceResult.Failure(ServiceErrors.CreateTimeout()));
        }
        catch (Exception exception) when(ShouldCreateErrorFromException(exception))
        {
            // cancellation can cause the wrong exception
            cancellationToken.ThrowIfCancellationRequested();

            // error contacting service
            return(ServiceResult.Failure(CreateErrorFromException(exception)));
        }
    }
        public async Task <ServiceResult <GenerateResponseDto> > GenerateAsync(GenerateRequestDto request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            try
            {
                var  input     = new NamedText(request.Definition?.Name ?? "", request.Definition?.Text ?? "");
                bool isSwagger = ServiceDefinitionUtility.DetectFormat(input) == ServiceDefinitionFormat.Swagger;
                var  service   = isSwagger ? new SwaggerParser().ParseDefinition(input) : new FsdParser().ParseDefinition(input);

                var generatorName = request.Generator?.Name;
                switch (generatorName)
                {
                case "csharp":
                    return(ServiceResult.Success(GenerateCode(() => new CSharpGenerator(), g => g.GenerateOutput(service))));

                case "javascript":
                    return(ServiceResult.Success(GenerateCode(() => new JavaScriptGenerator(), g => g.GenerateOutput(service))));

                case "typescript":
                    return(ServiceResult.Success(GenerateCode(() => new JavaScriptGenerator {
                        TypeScript = true
                    }, g => g.GenerateOutput(service))));

                case "markdown":
                    return(ServiceResult.Success(GenerateCode(() => new MarkdownGenerator(), g => g.GenerateOutput(service))));

                case "fsd":
                    return(ServiceResult.Success(GenerateCode(() => new FsdGenerator(), g => g.GenerateOutput(service))));

                case "swagger-json":
                    return(ServiceResult.Success(GenerateCode(() => new SwaggerGenerator(), g => g.GenerateOutput(service))));

                case "swagger-yaml":
                    return(ServiceResult.Success(GenerateCode(() => new SwaggerGenerator {
                        Yaml = true
                    }, g => g.GenerateOutput(service))));

                case "asp-net-web-api":
                    return(ServiceResult.Success(GenerateCode(() => new AspNetGenerator(), g => g.GenerateOutput(service))));

                case "crash":
                    throw new InvalidOperationException("Intentional exception for diagnostic purposes.");

                default:
                    return(ServiceResult.Failure(ServiceErrors.CreateInvalidRequest($"Unrecognized generator '{generatorName}'.")));
                }
            }
            catch (ServiceDefinitionException exception)
            {
                return(ServiceResult.Success(new GenerateResponseDto
                {
                    Failure = new FailureDto
                    {
                        Message = exception.Error,
                        Line = exception.Position.LineNumber,
                        Column = exception.Position.ColumnNumber,
                    },
                }));
            }
        }
Пример #9
0
 /// <summary>
 /// The HTTP header is not supported.
 /// </summary>
 public static ServiceErrorDto CreateHeaderNotSupported(string headerName) =>
 ServiceErrors.CreateInvalidRequest($"HTTP header '{headerName}' is not supported.");
Пример #10
0
 /// <summary>
 /// HTTP header has an invalid format.
 /// </summary>
 public static ServiceErrorDto CreateHeaderInvalidFormat(string headerName) =>
 ServiceErrors.CreateInvalidRequest($"HTTP header '{headerName}' has an invalid format.");
Пример #11
0
 /// <summary>
 /// HTTP content is invalid.
 /// </summary>
 public static ServiceErrorDto CreateInvalidContent(string message) =>
 ServiceErrors.CreateInvalidRequest($"HTTP content is invalid: {message}");
Пример #12
0
 public static ServiceErrorDto CreateInvalidRequestMissingWidgetId()
 {
     return(ServiceErrors.CreateInvalidRequest("The widget ID is missing."));
 }
Пример #13
0
 /// <summary>
 /// HTTP content missing Content-Type.
 /// </summary>
 public static ServiceErrorDto CreateMissingContentType() =>
 ServiceErrors.CreateInvalidRequest("HTTP content missing Content-Type.");
        private async Task HostAsync(HttpContext httpContext)
        {
            var httpRequest = httpContext.Request;
            var requestUrl  = httpRequest.GetEncodedUrl();

            var apiHandler = new ConformanceApiHttpHandler(new ConformanceApiService(m_tests));

            var requestMessage = new HttpRequestMessage(new HttpMethod(httpRequest.Method), requestUrl)
            {
                Content = new StreamContent(httpRequest.Body),
            };

            foreach (var header in httpRequest.Headers)
            {
                // Every header should be able to fit into one of the two header collections.
                // Try message.Headers first since that accepts more of them.
                if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable()))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable());
                }
            }

            HttpResponseMessage?responseMessage = null;
            ServiceErrorDto?    error           = null;

            try
            {
                responseMessage = await apiHandler.TryHandleHttpRequestAsync(requestMessage, httpContext.RequestAborted).ConfigureAwait(false);

                if (responseMessage == null)
                {
                    error = ServiceErrors.CreateInvalidRequest($"Test not found for {httpRequest.Method} {requestUrl}");
                }
            }
            catch (Exception exception)
            {
                error = ServiceErrorUtility.CreateInternalErrorForException(exception);
            }

            if (error != null)
            {
                var statusCode = HttpServiceErrors.TryGetHttpStatusCode(error.Code) ?? HttpStatusCode.InternalServerError;
                responseMessage = new HttpResponseMessage(statusCode)
                {
                    Content = JsonHttpContentSerializer.Instance.CreateHttpContent(error)
                };
            }

            if (responseMessage != null)
            {
                using (responseMessage)
                {
                    var response = httpContext.Response;
                    response.StatusCode = (int)responseMessage.StatusCode;

                    var responseHeaders = responseMessage.Headers;

                    // Ignore the Transfer-Encoding header if it is just "chunked".
                    // We let the host decide about whether the response should be chunked or not.
                    if (responseHeaders.TransferEncodingChunked == true && responseHeaders.TransferEncoding.Count == 1)
                    {
                        responseHeaders.TransferEncoding.Clear();
                    }

                    foreach (var header in responseHeaders)
                    {
                        response.Headers.Append(header.Key, header.Value.ToArray());
                    }

                    // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                    if (responseMessage.Content != null)
                    {
                        var contentHeaders = responseMessage.Content.Headers;

                        // Copy the response content headers only after ensuring they are complete.
                        // We ask for Content-Length first because HttpContent lazily computes this
                        // and only afterwards writes the value into the content headers.
                        _ = contentHeaders.ContentLength;

                        foreach (var header in contentHeaders)
                        {
                            response.Headers.Append(header.Key, header.Value.ToArray());
                        }

                        await responseMessage.Content.CopyToAsync(response.Body).ConfigureAwait(false);
                    }
                }
            }
        }
Пример #15
0
 public static ServiceErrorDto CreateInvalidRequestMissingWidgetIds()
 {
     return(ServiceErrors.CreateInvalidRequest("Must specify at least one widget ID."));
 }
 /// <summary>
 /// Called to create an error object from an unexpected exception.
 /// </summary>
 protected virtual ServiceErrorDto CreateErrorFromException(Exception exception) =>
 ServiceErrors.CreateInvalidRequest("Unexpected error while reading request body.");
    /// <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 (mapping == null)
        {
            throw new ArgumentNullException(nameof(mapping));
        }
        if (httpRequest == null)
        {
            throw new ArgumentNullException(nameof(httpRequest));
        }
        if (invokeMethodAsync == null)
        {
            throw new ArgumentNullException(nameof(invokeMethodAsync));
        }
        if (httpRequest.RequestUri == null)
        {
            throw new ArgumentException("RequestUri must be specified.", nameof(httpRequest));
        }

        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);
        }

        ServiceErrorDto?error = null;

        object?requestBody = null;

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

                if (requestResult.IsFailure)
                {
                    error = requestResult.Error;
                }
                else
                {
                    requestBody = requestResult.Value;
                }
            }
            catch (Exception exception) when(ShouldCreateErrorFromException(exception))
            {
                // cancellation can cause the wrong exception
                cancellationToken.ThrowIfCancellationRequested();

                // error reading request body
                error = CreateErrorFromException(exception);
            }
        }

        TResponse?response = null;

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

            var uriParameters = new Dictionary <string, string?>(StringComparer.OrdinalIgnoreCase);
            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, httpRequest.Content?.Headers) !);

            context.Request = request;

            if (!m_skipRequestValidation && !request.Validate(out var requestErrorMessage))
            {
                error = ServiceErrors.CreateInvalidRequest(requestErrorMessage);
            }
            else
            {
                var methodResult = await invokeMethodAsync(request, cancellationToken).ConfigureAwait(true);

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

                    if (!m_skipResponseValidation && !response.Validate(out var responseErrorMessage))
                    {
                        error    = ServiceErrors.CreateInvalidResponse(responseErrorMessage);
                        response = null;
                    }
                }
            }

            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 responseHeaders = mapping.GetResponseHeaders(response !);
                var headersResult   = HttpServiceUtility.TryAddNonContentHeaders(httpResponse.Headers, responseHeaders);
                if (headersResult.IsFailure)
                {
                    throw new InvalidOperationException(headersResult.Error !.Message);
                }

                if (responseMapping.ResponseBodyType != null)
                {
                    var serializer = GetHttpContentSerializer(responseMapping.ResponseBodyType);
                    var mediaType  = responseMapping.ResponseBodyContentType ?? responseHeaders?.GetContentType() ?? GetAcceptedMediaType(httpRequest, serializer);
                    httpResponse.Content = serializer.CreateHttpContent(responseMapping.GetResponseBody(response !) !, mediaType);
                    if (m_disableChunkedTransfer)
                    {
                        await httpResponse.Content.LoadIntoBufferAsync().ConfigureAwait(false);
                    }
                }
            }
            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)
            {
                var mediaType = GetAcceptedMediaType(httpRequest, m_contentSerializer);
                httpResponse.Content = m_contentSerializer.CreateHttpContent(error, mediaType);
                if (m_disableChunkedTransfer)
                {
                    await httpResponse.Content.LoadIntoBufferAsync().ConfigureAwait(false);
                }
            }
        }

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

        return(httpResponse);
    }
Пример #18
0
 /// <summary>
 /// HTTP content has unsupported Content-Type.
 /// </summary>
 public static ServiceErrorDto CreateUnsupportedContentType(string contentType) =>
 ServiceErrors.CreateInvalidRequest($"HTTP content has unsupported Content-Type: {contentType}");