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