Example #1
0
        private void ApplyParamTags(OpenApiRequestBody requestBody, RequestBodyFilterContext context, ParameterInfo parameterInfo)
        {
            if (!(parameterInfo.Member is MethodInfo methodInfo))
            {
                return;
            }

            // If method is from a constructed generic type, look for comments from the generic type method
            var targetMethod = methodInfo.DeclaringType.IsConstructedGenericType
                ? methodInfo.GetUnderlyingGenericTypeMethod()
                : methodInfo;

            if (targetMethod == null)
            {
                return;
            }

            var methodMemberName = XmlCommentsNodeNameHelper.GetMemberNameForMethod(targetMethod);
            var paramNode        = _xmlNavigator.SelectSingleNode(
                $"/doc/members/member[@name='{methodMemberName}']/param[@name='{parameterInfo.Name}']");

            if (paramNode != null)
            {
                requestBody.Description = XmlCommentsTextHelper.Humanize(paramNode.InnerXml);

                var example = paramNode.GetAttribute("example", "");
                if (string.IsNullOrEmpty(example))
                {
                    return;
                }

                foreach (var mediaType in requestBody.Content.Values)
                {
                    var exampleAsJson = (mediaType.Schema?.ResolveType(context.SchemaRepository) == "string")
                        ? $"\"{example}\""
                        : example;

                    mediaType.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson);
                }
            }
        }
Example #2
0
        private OpenApiRequestBody GenerateRequestBody(ServiceEntry apiDescription, SchemaRepository schemaRepository)
        {
            OpenApiRequestBody       requestBody   = null;
            RequestBodyFilterContext filterContext = null;
            var bodyParameter = apiDescription.ParameterDescriptors
                                .FirstOrDefault(paramDesc => paramDesc.From == ParameterFrom.Body);

            var formParameters = apiDescription.ParameterDescriptors
                                 .Where(paramDesc => paramDesc.From == ParameterFrom.Form);

            if (bodyParameter != null)
            {
                requestBody = GenerateRequestBodyFromBodyParameter(apiDescription, schemaRepository, bodyParameter);

                filterContext = new RequestBodyFilterContext(
                    bodyParameterDescription: bodyParameter,
                    formParameterDescriptions: null,
                    schemaGenerator: _schemaGenerator,
                    schemaRepository: schemaRepository);
            }
            else if (formParameters.Any())
            {
                requestBody = GenerateRequestBodyFromFormParameters(apiDescription, schemaRepository, formParameters);

                filterContext = new RequestBodyFilterContext(
                    bodyParameterDescription: null,
                    formParameterDescriptions: formParameters,
                    schemaGenerator: _schemaGenerator,
                    schemaRepository: schemaRepository);
            }

            if (requestBody != null)
            {
                foreach (var filter in _options.RequestBodyFilters)
                {
                    filter.Apply(requestBody, filterContext);
                }
            }

            return(requestBody);
        }
        public void Apply_WhenRequestIsANullableEnum_ShouldNotThrowException()
        {
            // Arrange
            serviceProvider.GetService(typeof(IExamplesProvider <Title?>)).Returns(new TitleExample());
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType()
                      {
                          Schema = new OpenApiSchema {
                              Reference = new OpenApiReference {
                                  Id = "definitions/Title"
                              }
                          }
                      } }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };

            var parameterDescriptions = new List <ApiParameterDescription>()
            {
                new ApiParameterDescription {
                    Type = typeof(Title?)
                }
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.RequestTakesANullableEnum), parameterDescriptions);

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            var actualParameterExample = Enum.Parse(typeof(Title), ((OpenApiString)requestBody.Content["application/json"].Example).Value);
            var expectedExample        = new TitleExample().GetExamples().Value;

            actualParameterExample.ShouldBe(expectedExample);
        }
Example #4
0
        private void ApplyPropertyTags(OpenApiRequestBody requestBody, PropertyInfo propertyInfo)
        {
            if (propertyInfo.DeclaringType != null && _excludedTypes.Any() && _excludedTypes.ToList().Contains(propertyInfo.DeclaringType))
            {
                return;
            }

            var propertyMemberName  = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(propertyInfo);
            var propertySummaryNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{propertyMemberName}']/{SummaryTag}");

            if (propertySummaryNode != null)
            {
                var propertyRemarksNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{propertyMemberName}']/{RemarksTag}");
                if (propertyRemarksNode != null &&
                    !string.IsNullOrWhiteSpace(propertyRemarksNode.InnerXml) &&
                    !requestBody.Description.Contains(XmlCommentsTextHelper.Humanize(propertyRemarksNode.InnerXml)))
                {
                    requestBody.Description +=
                        $" ({XmlCommentsTextHelper.Humanize(propertyRemarksNode.InnerXml)})";
                }
            }
        }
        public void Apply_WhenPassingDictionary_ShouldSetExampleOnRequestSchema()
        {
            // Arrange
            serviceProvider.GetService(typeof(IExamplesProvider <Dictionary <string, object> >)).Returns(new DictionaryAutoRequestExample());
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType()
                      {
                          Schema = new OpenApiSchema {
                              Reference = new OpenApiReference {
                                  Id = "definitions/object"
                              }
                          }
                      } }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };
            var parameterDescriptions = new List <ApiParameterDescription>()
            {
                new ApiParameterDescription {
                    Type = typeof(Dictionary <string, object>)
                }
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.DictionaryRequestAttribute), parameterDescriptions);

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            var actualExample = JsonConvert.DeserializeObject <Dictionary <string, object> >(((OpenApiString)requestBody.Content["application/json"].Example).Value);

            actualExample["PropertyInt"].ShouldBe(1);
            actualExample["PropertyString"].ShouldBe("Some string");
        }
Example #6
0
        public void SetsMultipleRequestExamples()
        {
            // Arrange
            serviceProvider.GetService(typeof(IMultipleExamplesProvider <PersonRequest>)).Returns(new PersonRequestMultipleExamples());
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType() }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };
            var parameterDescriptions = new List <ApiParameterDescription>()
            {
                new ApiParameterDescription {
                    Type = typeof(PersonRequest)
                }
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.PersonRequestUnannotated), parameterDescriptions);

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            var actualExamples   = requestBody.Content["application/json"].Examples;
            var expectedExamples = new PersonRequestMultipleExamples().GetExamples();

            actualExamples.ShouldAllMatch(expectedExamples, ExampleAssertExtensions.ShouldMatch);
            actualExamples["Dave"].Description.ShouldBe("Here's a description");
            actualExamples["Angela"].Description.ShouldBeNull();

            // Assert SerializeAsV2
            var actualSchemaExample = JsonConvert.DeserializeObject <PersonRequest>(((OpenApiString)filterContext.SchemaRepository.Schemas["PersonRequest"].Example).Value);

            actualSchemaExample.ShouldMatch(expectedExamples.First().Value);
        }
        private static OpenApiRequestBody CreateRequestBody(
            ParsingContext context,
            OpenApiParameter bodyParameter)
        {
            var consumes = context.GetFromTempStorage <List <string> >("operationproduces") ??
                           context.GetFromTempStorage <List <string> >("globalproduces") ?? new List <string> {
                "application/json"
            };

            var requestBody = new OpenApiRequestBody
            {
                Description = bodyParameter.Description,
                Required    = bodyParameter.Required,
                Content     = consumes.ToDictionary(
                    k => k,
                    v => new OpenApiMediaType
                {
                    Schema = bodyParameter.Schema     // Should we clone this?
                })
            };

            return(requestBody);
        }
        public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
        {
            var bodyParameterDescription = context.BodyParameterDescription;

            if (bodyParameterDescription == null)
            {
                return;
            }

            var properties = bodyParameterDescription.Type.GetProperties();

            foreach (var propertyInfo in properties)
            {
                ApplyPropertyTags(requestBody, propertyInfo);
                return;
            }
            // var parameterInfo = bodyParameterDescription.ParameterInfo();
            // if (parameterInfo != null)
            // {
            //     ApplyParamTags(requestBody, parameterInfo);
            //     return;
            // }
        }
Example #9
0
        public void WhenRequestIncorrect_ShouldNotThrowException()
        {
            // Arrange
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType() }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.AnnotatedWithIncorrectSwaggerRequestExampleAttribute));

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            // this assertion fails but it's not really a problem, since ASP.NET WebApi only accepts one [FromBody] in the request.
            // var actualExample = JsonConvert.DeserializeObject<PersonRequest>(((OpenApiRawString)requestBody.Content["application/json"].Example).Value);
            // actualExample.ShouldBeNull();
        }
        public void SetsRequestExamplesForInterface_FromMethodAttributes()
        {
            // Arrange
            serviceProvider.GetService(typeof(IExamplesProvider <IPersonRequest>)).Returns(new IPersonRequestAutoExample());
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType() }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };
            var parameterDescriptions = new List <ApiParameterDescription>()
            {
                new ApiParameterDescription {
                    Type = typeof(IPersonRequest)
                }
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.IPersonRequestUnannotated), parameterDescriptions);

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            var actualExample   = JsonConvert.DeserializeObject <PersonRequest>(((OpenApiRawString)requestBody.Content["application/json"].Example).Value);
            var expectedExample = new PersonRequestAutoExample().GetExamples();

            actualExample.ShouldMatch(expectedExample);

            // Assert SerializeAsV2
            var actualSchemaExample = JsonConvert.DeserializeObject <PersonRequest>(((OpenApiRawString)filterContext.SchemaRepository.Schemas["IPersonRequest"].Example).Value);

            actualSchemaExample.ShouldMatch(expectedExample);
        }
Example #11
0
        private void ValidateContent(OpenApiRequestBody requestBodySpec, OpenApiDocument openApiDocument, HttpContent content)
        {
            requestBodySpec = (requestBodySpec.Reference != null)
                ? (OpenApiRequestBody)openApiDocument.ResolveReference(requestBodySpec.Reference)
                : requestBodySpec;

            if (requestBodySpec.Required && content == null)
            {
                throw new RequestDoesNotMatchSpecException("Required content is not present");
            }

            if (content == null)
            {
                return;
            }

            if (!requestBodySpec.Content.TryGetValue(content.Headers.ContentType.MediaType, out OpenApiMediaType mediaTypeSpec))
            {
                throw new RequestDoesNotMatchSpecException($"Content media type '{content.Headers.ContentType.MediaType}' is not specified");
            }

            try
            {
                foreach (var contentValidator in _contentValidators)
                {
                    if (contentValidator.CanValidate(content.Headers.ContentType.MediaType))
                    {
                        contentValidator.Validate(mediaTypeSpec, openApiDocument, content);
                    }
                }
            }
            catch (ContentDoesNotMatchSpecException contentException)
            {
                throw new RequestDoesNotMatchSpecException($"Content does not match spec. {contentException.Message}");
            }
        }
Example #12
0
        internal static OpenApiRequestBody CreateRequestBody(
            ParsingContext context,
            OpenApiParameter bodyParameter)
        {
            var consumes = context.GetFromTempStorage <List <string> >(TempStorageKeys.OperationConsumes) ??
                           context.GetFromTempStorage <List <string> >(TempStorageKeys.GlobalConsumes) ??
                           new List <string> {
                "application/json"
            };

            var requestBody = new OpenApiRequestBody
            {
                Description = bodyParameter.Description,
                Required    = bodyParameter.Required,
                Content     = consumes.ToDictionary(
                    k => k,
                    v => new OpenApiMediaType
                {
                    Schema = bodyParameter.Schema
                })
            };

            return(requestBody);
        }
        public void Apply_WhenPassingDictionary_ShouldSetExampleOnRequestSchema()
        {
            // Arrange
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType() }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.AnnotatedWithDictionarySwaggerRequestExampleAttribute));

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            var actualExample = JsonConvert.DeserializeObject <Dictionary <string, object> >(((OpenApiRawString)requestBody.Content["application/json"].Example).Value);

            actualExample["PropertyInt"].ShouldBe(1);
            actualExample["PropertyString"].ShouldBe("Some string");
        }
Example #14
0
        private static OpenApiRequestBody GetRequestBody(string route, List <JimuServiceParameterDesc> paras, string httpMethod)
        {
            if (httpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }
            var bodyParas = paras.Where(x => route.IndexOf($"{{{x.Name}}}") < 0).ToList();

            var reqBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>(),
            };
            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = _schemaFactory.GetProperties(bodyParas)
            };

            reqBody.Content.Add("application/json", new OpenApiMediaType
            {
                Schema = schema
            });
            return(reqBody);
        }
        public void Apply_SetsRequestExamples_FromMethodAttributes()
        {
            // Arrange
            var requestBody = new OpenApiRequestBody
            {
                Content = new Dictionary <string, OpenApiMediaType>
                {
                    { "application/json", new OpenApiMediaType() }
                }
            };
            var operation = new OpenApiOperation {
                OperationId = "foobar", RequestBody = requestBody
            };
            var filterContext = FilterContextFor(typeof(FakeActions), nameof(FakeActions.AnnotatedWithSwaggerRequestExampleAttribute));

            // Act
            sut.Apply(operation, filterContext);

            // Assert
            var actualExample   = JsonConvert.DeserializeObject <PersonRequest>(((OpenApiRawString)requestBody.Content["application/json"].Example).Value);
            var expectedExample = (PersonRequest) new PersonRequestExample().GetExamples();

            actualExample.ShouldMatch(expectedExample);
        }
 /// <summary>
 /// Gets the schema for the JSON media type, if any.
 /// </summary>
 public static OpenApiSchema?GetJsonSchema(this OpenApiRequestBody request)
 => request.Content.GetJsonSchema();
 public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
 {
     requestBody.Extensions.Add("X-foo", new OpenApiString("bar"));
     requestBody.Extensions.Add("X-docName", new OpenApiString(context.DocumentName));
 }
 public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
 {
     requestBody.Extensions.Add("X-foo", new OpenApiString("bar"));
 }
        //if (!parameter.AllowEmptyValue)
        //validator.AddRule(BuildRequired(_validatorContext, parameter));
        //private IValidate BuildRequired(IValidatorContext validatorContext, IOpenApiElement openApiElement)
        //{
        //return new OpenApiRequiredRule<IOpenApiElement>(validatorContext, openApiElement);

        //switch (schema.Type)
        //{
        //	case "string":
        //		new ValidatorRule<string, IOpenApiElement>(validatorContext, openApiElement);
        //		break;
        //	case "boolean":
        //		new ValidatorRule<bool, IOpenApiElement>(validatorContext, openApiElement);
        //		break;
        //	case "boolean":
        //		new ValidatorRule<bool, IOpenApiElement>(validatorContext, openApiElement);
        //		break;
        //	default:
        //		break;
        //}
        //return null;
        //}

        /// <summary>
        ///
        /// </summary>
        public IValidate Build(OpenApiRequestBody requestBody)
        {
            IValidate validator = new OpenApiBodyValidator(_validatorContext, requestBody);

            return(validator);
        }
        public static T DeserializeDataContractXmlExampleAs <T>(this OpenApiRequestBody response)
        {
            var value = ((OpenApiString)response.Content["application/xml"].Example).Value;

            return(DeserializeDataContractXmlAs <T>(value));
        }
Example #21
0
 public override void Visit(OpenApiRequestBody requestBody)
 {
     RequestBodyCount++;
 }
Example #22
0
        private static void CreateOperationsFromRoutes(HttpFunctionDefinition[] functionDefinitions,
                                                       OpenApiDocument openApiDocument, SchemaReferenceRegistry registry, string apiPrefix)
        {
            string prependedApiPrefix = string.IsNullOrEmpty(apiPrefix) ? $"" : $"/{apiPrefix}";
            var    operationsByRoute  = functionDefinitions.Where(x => x.Route != null).GroupBy(x => $"{prependedApiPrefix}/{x.Route}");

            foreach (IGrouping <string, HttpFunctionDefinition> route in operationsByRoute)
            {
                OpenApiPathItem pathItem = new OpenApiPathItem()
                {
                    Operations = new Dictionary <OperationType, OpenApiOperation>()
                };

                foreach (HttpFunctionDefinition functionByRoute in route)
                {
                    Type commandType = functionByRoute.CommandType;
                    foreach (HttpMethod method in functionByRoute.Verbs)
                    {
                        OpenApiOperation operation = new OpenApiOperation
                        {
                            Description = functionByRoute.OpenApiDescription,
                            Responses   = new OpenApiResponses(),
                            Tags        = string.IsNullOrWhiteSpace(functionByRoute.RouteConfiguration.OpenApiName) ? null : new List <OpenApiTag>()
                            {
                                new OpenApiTag {
                                    Name = functionByRoute.RouteConfiguration.OpenApiName
                                }
                            }
                        };
                        foreach (KeyValuePair <int, string> kvp in functionByRoute.OpenApiResponseDescriptions)
                        {
                            operation.Responses.Add(kvp.Key.ToString(), new OpenApiResponse
                            {
                                Description = kvp.Value
                            });
                        }

                        if (!operation.Responses.ContainsKey("200"))
                        {
                            OpenApiResponse response = new OpenApiResponse
                            {
                                Description = "Successful API operation"
                            };
                            if (functionByRoute.CommandResultType != null)
                            {
                                OpenApiSchema schema = registry.FindOrAddReference(functionByRoute.CommandResultType);
                                response.Content = new Dictionary <string, OpenApiMediaType>
                                {
                                    { "application/json", new OpenApiMediaType {
                                          Schema = schema
                                      } }
                                };
                            }
                            operation.Responses.Add("200", response);
                        }

                        string lowerCaseRoute = functionByRoute.Route;
                        foreach (HttpParameter property in functionByRoute.PossibleBindingProperties)
                        {
                            if (method == HttpMethod.Get || method == HttpMethod.Delete)
                            {
                                operation.Parameters.Add(new OpenApiParameter
                                {
                                    Name        = property.Name.ToCamelCase(),
                                    In          = ParameterLocation.Query,
                                    Required    = !property.IsOptional,
                                    Schema      = property.Type.MapToOpenApiSchema(),
                                    Description = ""
                                });
                            }
                        }

                        if (functionByRoute.Authorization == AuthorizationTypeEnum.Function && method == HttpMethod.Get || method == HttpMethod.Delete)
                        {
                            operation.Parameters.Add(new OpenApiParameter
                            {
                                Name        = "code",
                                In          = ParameterLocation.Query,
                                Required    = true,
                                Schema      = typeof(string).MapToOpenApiSchema(),
                                Description = ""
                            });
                        }

                        foreach (HttpParameter property in functionByRoute.RouteParameters)
                        {
                            operation.Parameters.Add(new OpenApiParameter
                            {
                                Name        = property.RouteName.ToCamelCase(),
                                In          = ParameterLocation.Path,
                                Required    = !property.IsOptional,
                                Schema      = property.Type.MapToOpenApiSchema(),
                                Description = ""
                            });
                            // TODO: We need to consider what to do with the payload model here - if its a route parameter
                            // we need to ignore it in the payload model
                        }

                        if (method == HttpMethod.Post || method == HttpMethod.Put || method == HttpMethod.Patch)
                        {
                            OpenApiRequestBody requestBody = new OpenApiRequestBody();
                            OpenApiSchema      schema      = registry.FindReference(commandType);
                            requestBody.Content = new Dictionary <string, OpenApiMediaType>
                            {
                                { "application/json", new OpenApiMediaType {
                                      Schema = schema
                                  } }
                            };
                            operation.RequestBody = requestBody;
                        }


                        pathItem.Operations.Add(MethodToOperationMap[method], operation);
                    }
                }

                openApiDocument.Paths.Add(route.Key, pathItem);
            }
        }
Example #23
0
        private static void CreateOperationsFromRoutes(HttpFunctionDefinition[] functionDefinitions,
                                                       OpenApiDocument openApiDocument, SchemaReferenceRegistry registry, string apiPrefix, OpenApiCompilerConfiguration compilerConfiguration)
        {
            string prependedApiPrefix = string.IsNullOrEmpty(apiPrefix) ? $"" : $"/{apiPrefix}";
            var    operationsByRoute  = functionDefinitions.Where(x => x.Route != null).GroupBy(x => $"{prependedApiPrefix}/{x.Route}");

            foreach (IGrouping <string, HttpFunctionDefinition> route in operationsByRoute)
            {
                OpenApiPathItem pathItem = new OpenApiPathItem()
                {
                    Operations = new Dictionary <OperationType, OpenApiOperation>()
                };

                foreach (HttpFunctionDefinition functionByRoute in route)
                {
                    Type commandType = functionByRoute.CommandType;
                    foreach (HttpMethod method in functionByRoute.Verbs)
                    {
                        OpenApiOperation operation = new OpenApiOperation
                        {
                            Description = functionByRoute.OpenApiDescription,
                            Summary     = functionByRoute.OpenApiSummary,
                            Responses   = new OpenApiResponses(),
                            Tags        = string.IsNullOrWhiteSpace(functionByRoute.RouteConfiguration.OpenApiName) ? null : new List <OpenApiTag>()
                            {
                                new OpenApiTag {
                                    Name = functionByRoute.RouteConfiguration.OpenApiName
                                }
                            }
                        };

                        var operationFilterContext = new OpenApiOperationFilterContext
                        {
                            CommandType   = commandType,
                            PropertyNames = new Dictionary <string, string>()
                        };

                        foreach (KeyValuePair <int, OpenApiResponseConfiguration> kvp in functionByRoute.OpenApiResponseConfigurations)
                        {
                            operation.Responses.Add(kvp.Key.ToString(), new OpenApiResponse
                            {
                                Description = kvp.Value.Description,
                                Content     =
                                {
                                    ["application/json"] = new OpenApiMediaType()
                                    {
                                    Schema = kvp.Value.ResponseType == null ? null : registry.FindOrAddReference(kvp.Value.ResponseType)
                                    }
                                }
                            });
                        }

                        // Does any HTTP success response (2xx) exist
                        if (operation.Responses.Keys.FirstOrDefault(x => x.StartsWith("2")) == null)
                        {
                            OpenApiResponse response = new OpenApiResponse
                            {
                                Description = "Successful API operation"
                            };
                            if (functionByRoute.CommandResultType != null)
                            {
                                OpenApiSchema schema = registry.FindOrAddReference(functionByRoute.CommandResultType);
                                response.Content = new Dictionary <string, OpenApiMediaType>
                                {
                                    { "application/json", new OpenApiMediaType {
                                          Schema = schema
                                      } }
                                };
                            }
                            operation.Responses.Add("200", response);
                        }

                        if (method == HttpMethod.Get || method == HttpMethod.Delete)
                        {
                            var schema = registry.GetOrCreateSchema(commandType);
                            foreach (HttpParameter property in functionByRoute.PossibleBindingProperties)
                            {
                                var propertyInfo = commandType.GetProperty(property.Name);

                                // Property Name
                                var propertyName = propertyInfo.GetAttributeValue((JsonPropertyAttribute attribute) => attribute.PropertyName);
                                if (string.IsNullOrWhiteSpace(propertyName))
                                {
                                    propertyName = propertyInfo.GetAttributeValue((DataMemberAttribute attribute) => attribute.Name);
                                }
                                if (string.IsNullOrWhiteSpace(propertyName))
                                {
                                    propertyName = propertyInfo.Name.ToCamelCase();
                                }

                                // Property Required
                                var propertyRequired = !property.IsOptional;
                                if (!propertyRequired)
                                {
                                    propertyRequired = propertyInfo.GetAttributeValue((JsonPropertyAttribute attribute) => attribute.Required) == Required.Always;
                                }
                                if (!propertyRequired)
                                {
                                    propertyRequired = propertyInfo.GetAttributeValue((RequiredAttribute attribute) => attribute) != null;
                                }

                                var propertySchema = schema.Properties[propertyName];

                                var parameter = new OpenApiParameter
                                {
                                    Name        = propertyName,
                                    In          = ParameterLocation.Query,
                                    Required    = propertyRequired,
                                    Schema      = propertySchema, // property.Type.MapToOpenApiSchema(),
                                    Description = propertySchema.Description
                                };

                                FilterParameter(compilerConfiguration.ParameterFilters, parameter);

                                operation.Parameters.Add(parameter);
                                operationFilterContext.PropertyNames[parameter.Name] = propertyInfo.Name;
                            }
                        }

                        if (functionByRoute.Authorization == AuthorizationTypeEnum.Function && (method == HttpMethod.Get || method == HttpMethod.Delete))
                        {
                            operation.Parameters.Add(new OpenApiParameter
                            {
                                Name        = "code",
                                In          = ParameterLocation.Query,
                                Required    = true,
                                Schema      = typeof(string).MapToOpenApiSchema(),
                                Description = ""
                            });
                        }

                        foreach (HttpParameter property in functionByRoute.RouteParameters)
                        {
                            var parameter = new OpenApiParameter
                            {
                                Name        = property.RouteName.ToCamelCase(),
                                In          = ParameterLocation.Path,
                                Required    = !property.IsOptional,
                                Schema      = property.Type.MapToOpenApiSchema(),
                                Description = ""
                            };

                            FilterParameter(compilerConfiguration.ParameterFilters, parameter);

                            operation.Parameters.Add(parameter);
                            // TODO: We need to consider what to do with the payload model here - if its a route parameter
                            // we need to ignore it in the payload model
                        }

                        if (method == HttpMethod.Post || method == HttpMethod.Put || method == HttpMethod.Patch)
                        {
                            OpenApiRequestBody requestBody = new OpenApiRequestBody();
                            OpenApiSchema      schema      = registry.FindReference(commandType);
                            requestBody.Content = new Dictionary <string, OpenApiMediaType>
                            {
                                { "application/json", new OpenApiMediaType {
                                      Schema = schema
                                  } }
                            };
                            operation.RequestBody = requestBody;
                        }

                        FilterOperation(compilerConfiguration.OperationFilters, operation, operationFilterContext);

                        pathItem.Operations.Add(MethodToOperationMap[method], operation);
                    }
                }

                openApiDocument.Paths.Add(route.Key, pathItem);
            }
        }
        private IEnumerable <Tuple <string, OpenApiPathItem> > BuildPaths(
            string resource, DocumentFilterContext context,
            IEnumerable <PolicyMemberBinding> bindings)
        {
            var validationErrorsSchema = context.SchemaGenerator.GenerateSchema(
                typeof(ValidationErrors[]), context.SchemaRepository);

            validationErrorsSchema.Example = CreateExampleJson(new[]
            {
                new ValidationErrors
                {
                    PropertyName = "SomeProperty",
                    Errors       = new [] { "'Some Property' is required" },
                    Nested       = new []
                    {
                        new ValidationErrors
                        {
                            PropertyName = "NestedProperty",
                            Errors       = new [] { "'Nested Property' not in range" }
                        }
                    }
                }
            });

            return(bindings.Select(x =>
            {
                var requestType = x.Key as Type;
                if (requestType == null || requestType.IsAbstract ||
                    requestType.ContainsGenericParameters)
                {
                    return null;
                }

                var responseType = x.Dispatcher.LogicalReturnType;
                var handler = x.Dispatcher.Owner.HandlerType;
                var assembly = requestType.Assembly.GetName();
                var tag = $"{assembly.Name} - {assembly.Version}";
                var requestSchema = GetMessageSchema(requestType, context);
                var responseSchema = GetMessageSchema(responseType, context);
                var requestPath = HttpOptionsExtensions.GetRequestPath(requestType);
                var handlerAssembly = handler.Assembly.GetName();
                var handlerNotes = $"Handled by {handler.FullName} in {handlerAssembly.Name} - {handlerAssembly.Version}";

                var operation = new OpenApiOperation
                {
                    Summary = requestSchema.Description,
                    OperationId = requestType.FullName,
                    Description = handlerNotes,
                    Tags = new List <OpenApiTag> {
                        new() { Name = tag }
                    },
                    RequestBody = new OpenApiRequestBody
                    {
                        Description = "request to process",
                        Content = JsonFormats.Select(f =>
                                                     new { Format = f, Media = new OpenApiMediaType
                                                           {
                                                               Schema = requestSchema,
                                                               Example = requestSchema.Example
                                                           } }).ToDictionary(f => f.Format, f => f.Media),
                        Required = true
                    },
                    Responses =
                    {
                        {
                            "200", new OpenApiResponse
                            {
                                Description = "OK",
                                Content = JsonFormats.Select(f =>
                                                             new   { Format = f, Media = new OpenApiMediaType
                                                                     {
                                                                         Schema = responseSchema,
                                                                         Example = responseSchema.Example
                                                                     } }).ToDictionary(f => f.Format, f => f.Media)
                            }
                        },
 public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
 {
     requestBody.Required = true;
 }
Example #26
0
 public override void Visit(OpenApiRequestBody requestBody)
 {
     EncodeCall();
     base.Visit(requestBody);
 }
Example #27
0
 /// <inheritdoc/>
 public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
 {
     requestBody.Description = requestBody.Description.SingleSpacesNoLineBreak();
 }
 public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context)
 {
     requestBody.Extensions.Add("x-purpose", new OpenApiString("test"));
 }
Example #29
0
 /// <summary>
 /// Visits <see cref="OpenApiRequestBody"/>
 /// </summary>
 public virtual void Visit(OpenApiRequestBody requestBody)
 {
 }
Example #30
0
        private OpenApiRequestBody GenerateRequestBody(IEndPointMethodHandler endPointMethodHandler, XElement element)
        {
            var requestParameter =
                endPointMethodHandler.Configuration.Parameters.FirstOrDefault(p =>
                                                                              p.ParameterSource == EndPointMethodParameterSource.PostBody);

            if (requestParameter != null)
            {
                var request = new OpenApiRequestBody
                {
                    Content = new Dictionary <string, OpenApiMediaType>()
                };

                var schema = _apiSchemaGenerator.GetSchemaType(requestParameter.ParamType);

                foreach (var schemaProperty in schema.Properties)
                {
                    schemaProperty.Value.Description = element.GetParameterSummary(schemaProperty.Key);
                }

                foreach (var contentType in _contentSerializationService.SupportedContentTypes)
                {
                    request.Content[contentType] = new OpenApiMediaType
                    {
                        Schema = schema
                    };
                }

                return(request);
            }

            var postParameterList = endPointMethodHandler.Configuration.Parameters.Where(p =>
                                                                                         p.ParameterSource == EndPointMethodParameterSource.PostParameter).ToList();

            if (postParameterList.Count > 0)
            {
                var request = new OpenApiRequestBody
                {
                    Content = new Dictionary <string, OpenApiMediaType>()
                };

                var schema = GeneratePostParameterSchema(postParameterList);

                schema.Xml = new OpenApiXml
                {
                    Name = "args"
                };

                foreach (var schemaProperty in schema.Properties)
                {
                    schemaProperty.Value.Description = element.GetParameterSummary(schemaProperty.Key);
                }

                foreach (var contentType in _contentSerializationService.SupportedContentTypes)
                {
                    request.Content[contentType] = new OpenApiMediaType
                    {
                        Schema = schema
                    };
                }

                return(request);
            }

            return(null);
        }