Example #1
0
        private static OpenApiResult GetOpenApiResultForPoco(object result, OpenApiOperation operation, ILogger logger)
        {
            logger.LogDebug(
                "Attempting to get OpenAPI result for with POCO with [{operation}]",
                operation.GetOperationId());
#pragma warning disable IDE0007 // Use implicit type - see https://github.com/dotnet/roslyn/issues/30450
            List <KeyValuePair <string, OpenApiResponse> > successResponses = operation
#pragma warning restore IDE0007 // Use implicit type
                                                                              .Responses
                                                                              .Where(r => r.Key == "default" || (r.Key.Length == 3 && r.Key[0] == '2'))
                                                                              .ToList();
            if (successResponses.Count != 1)
            {
                throw new OpenApiServiceMismatchException($"An OpenApi service can only return a plain old CLR object (POCO) for operations that define exactly one success response (including the default response, if present), but '{operation.OperationId}' defines '{successResponses.Count}'. Return an {nameof(OpenApiResult)} instead, or modify the service definition to define a single successful response.");
            }

            KeyValuePair <string, OpenApiResponse> response = successResponses.Single();
            var openApiResult = new OpenApiResult
            {
                // Use the status code for the first response
                StatusCode = int.Parse(response.Key),
            };

            foreach (KeyValuePair <string, OpenApiMediaType> mediaType in response.Value.Content)
            {
                // Add all our candidate media types in
                openApiResult.Results.Add(mediaType.Key, result);
            }

            logger.LogDebug(
                "Got openAPIResult [{apiResult}] for poco with [{operation}]",
                openApiResult.Results.Keys,
                operation.GetOperationId());
            return(openApiResult);
        }
        /// <inheritdoc/>
        public IActionResult BuildOutput(object result, OpenApiOperation operation)
        {
            if (this.logger.IsEnabled(LogLevel.Debug))
            {
                this.logger.LogDebug(
                    "Building output for [{operation}]",
                    operation.GetOperationId());
            }

            // This must have been called after CanBuildOutput(), so we know these casts
            // and lookups will succeed
            var openApiResult = (OpenApiResult)result;

            var actionResult = OpenApiActionResult.FromOpenApiResult(openApiResult, operation, this.converters, this.logger);

            if (this.logger.IsEnabled(LogLevel.Debug))
            {
                this.logger.LogDebug(
                    "Built output for [{operation}]",
                    operation.GetOperationId());
            }

            return(actionResult);
        }
        /// <inheritdoc/>
        public OpenApiResult GetResponse(Exception exception, OpenApiOperation operation)
        {
            Type exceptionType = exception.GetType();
            OpenApiMappedException mappedException = this.GetMappedException(operation, exceptionType);

            IExceptionMapper mapper = this.GetExceptionMapperFor(mappedException, exception, operation);

            if (mapper == null)
            {
                string operationId = operation.GetOperationId();
                this.logger.LogError(
                    "Unmapped exception thrown by [{operationId}]: [{exception}]",
                    operationId,
                    exception);
                throw new OpenApiServiceMismatchException($"Operation {operationId} has thrown an exception of type {exception.GetType().FullName}. You should either handle this in your service, or add an exception mapping defining which status code this exception corresponds to.");
            }

            return(mapper.MapException(operation.Responses, exception, mappedException?.StatusCode));
        }