Esempio n. 1
0
        private void ApplyPropertyTags(OpenApiParameter parameter, ParameterFilterContext context)
        {
            var propertyMemberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(context.PropertyInfo);
            var propertyNode       = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{propertyMemberName}']");

            if (propertyNode == null)
            {
                return;
            }

            var summaryNode = propertyNode.SelectSingleNode("summary");

            if (summaryNode != null)
            {
                parameter.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml);
            }

            var exampleNode = propertyNode.SelectSingleNode("example");

            if (exampleNode != null)
            {
                var exampleAsJson = (parameter.Schema?.ResolveType(context.SchemaRepository) == "string")
                    ? $"\"{exampleNode.InnerXml}\""
                    : exampleNode.InnerXml;

                parameter.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson);
            }
        }
Esempio n. 2
0
        private void FillSchema(OpenApiSchema schema, SchemaFilterContext context, IPropertySet propertySet)
        {
            schema.Type       = "object";
            schema.Items      = null;
            schema.Properties = new Dictionary <string, OpenApiSchema>();

            foreach (IProperty property in propertySet.GetProperties())
            {
                OpenApiSchema?propertySchema = context.SchemaGenerator.GenerateSchema(property.Type, context.SchemaRepository);
                propertySchema.Description = property.Description ?? propertySchema.Description;

                if (property.GetOrEvaluateNullability() is { } allowNull)
                {
                    propertySchema.Nullable = allowNull.IsNullAllowed;
                }

                if (property.GetAllowedValuesUntyped() is { } allowedValues)
                {
                    propertySchema.Enum = new List <IOpenApiAny>();
                    foreach (object allowedValue in allowedValues.ValuesUntyped)
                    {
                        string      jsonValue  = JsonConverterFunc(allowedValue);
                        IOpenApiAny openApiAny = OpenApiAnyFactory.CreateFromJson(jsonValue);
                        propertySchema.Enum.Add(openApiAny);
                    }
                }

                string?propertyName = _options.ResolvePropertyName !(property.Name);
                schema.Properties.Add(propertyName, propertySchema);
            }
        }
Esempio n. 3
0
        private OpenApiSchema CreatePrimitiveSchema(DataContract dataContract)
        {
            var schema = new OpenApiSchema
            {
                Type   = dataContract.DataType.ToString().ToLower(CultureInfo.InvariantCulture),
                Format = dataContract.DataFormat
            };

            // For backcompat only - EnumValues is obsolete
            if (dataContract.EnumValues != null)
            {
                schema.Enum = dataContract.EnumValues
                              .Select(value => JsonSerializer.Serialize(value))
                              .Select(valueAsJson => OpenApiAnyFactory.CreateFromJson(valueAsJson))
                              .ToList();

                return(schema);
            }

            if (dataContract.UnderlyingType.IsEnum)
            {
                schema.Enum = dataContract.UnderlyingType.GetEnumValues()
                              .Cast <object>()
                              .Distinct()
                              .Select(value => dataContract.JsonConverter(value))
                              .Select(valueAsJson => OpenApiAnyFactory.CreateFromJson(valueAsJson))
                              .ToList();
            }

            return(schema);
        }
 public static void ConfigureDomainTypes(this SwaggerGenOptions c)
 {
     c.MapType <Sensitive <string> >(() =>
                                     new OpenApiSchema
     {
         Type = "string",
     });
     c.MapType <Pan>(() =>
                     new OpenApiSchema
     {
         Type      = "string",
         MinLength = 16,
         MaxLength = 16,
         Example   = OpenApiAnyFactory.CreateFromJson("1111222233334444")
     });
     c.MapType <Cvv>(() =>
                     new OpenApiSchema
     {
         Type    = "string",
         Example = OpenApiAnyFactory.CreateFromJson("123")
     });
     c.MapType <ExpiryMonth>(() =>
                             new OpenApiSchema
     {
         Type    = "string",
         Pattern = "/([0-9]{4})-(?:[0-9]{2})/",
         Example = OpenApiAnyFactory.CreateFromJson("2021-01")
     });
 }
Esempio n. 5
0
        private OpenApiSchema GenerateSchemaForParameter(ParameterInfo parameterInfo, SchemaRepository schemaRepository)
        {
            var dataContract = GetDataContractFor(parameterInfo.ParameterType);

            var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts)
                ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts)
                : GenerateConcreteSchema(dataContract, schemaRepository);

            if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null)
            {
                schema.AllOf = new[] { new OpenApiSchema {
                                           Reference = schema.Reference
                                       } };
                schema.Reference = null;
            }

            if (schema.Reference == null)
            {
                if (parameterInfo.HasDefaultValue)
                {
                    var defaultAsJson = dataContract.JsonConverter(parameterInfo.DefaultValue);
                    schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson);
                }

                schema.ApplyValidationAttributes(parameterInfo.GetCustomAttributes());

                ApplyFilters(schema, parameterInfo.ParameterType, schemaRepository, parameterInfo: parameterInfo);
            }

            return(schema);
        }
Esempio n. 6
0
        /// <summary>
        /// 实现过滤器方法
        /// </summary>
        /// <param name="model"></param>
        /// <param name="context"></param>
        public void Apply(OpenApiSchema model, SchemaFilterContext context)
        {
            var type = context.Type;

            // 排除其他程序集的枚举
            if (type.IsEnum && App.Assemblies.Contains(type.Assembly))
            {
                model.Enum.Clear();
                var stringBuilder = new StringBuilder();
                stringBuilder.Append($"{model.Description}<br />");

                var enumValues = Enum.GetValues(type);
                // 获取枚举实际值类型
                var enumValueType = type.GetField("value__").FieldType;

                foreach (var value in enumValues)
                {
                    var numValue = value.ChangeType(enumValueType);

                    // 获取枚举成员特性
                    var fieldinfo            = type.GetField(Enum.GetName(type, value));
                    var descriptionAttribute = fieldinfo.GetCustomAttribute <DescriptionAttribute>(true);
                    model.Enum.Add(OpenApiAnyFactory.CreateFromJson($"{numValue}"));

                    stringBuilder.Append($"&nbsp;{descriptionAttribute?.Description} {value} = {numValue}<br />");
                }
                model.Description = stringBuilder.ToString();
            }
        }
Esempio n. 7
0
        private OpenApiSchema GenerateSchemaForMember(
            MemberInfo memberInfo,
            SchemaRepository schemaRepository,
            DataProperty dataProperty = null)
        {
            var memberType = memberInfo.MemberType == MemberTypes.Field
                ? ((FieldInfo)memberInfo).FieldType
                : ((PropertyInfo)memberInfo).PropertyType;

            var dataContract = GetDataContractFor(memberType);

            var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts)
                ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts)
                : GenerateConcreteSchema(dataContract, schemaRepository);

            if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null)
            {
                schema.AllOf = new[] { new OpenApiSchema {
                                           Reference = schema.Reference
                                       } };
                schema.Reference = null;
            }

            if (schema.Reference == null)
            {
                var customAttributes = memberInfo.GetInlineAndMetadataAttributes();

                // Nullable, ReadOnly & WriteOnly are only relevant for Schema "properties" (i.e. where dataProperty is non-null)
                if (dataProperty != null)
                {
                    schema.Nullable = _generatorOptions.SupportNonNullableReferenceTypes
                        ? dataProperty.IsNullable && !customAttributes.OfType <RequiredAttribute>().Any() && !memberInfo.IsNonNullable()
                        : dataProperty.IsNullable && !customAttributes.OfType <RequiredAttribute>().Any();

                    schema.ReadOnly  = dataProperty.IsReadOnly;
                    schema.WriteOnly = dataProperty.IsWriteOnly;
                }

                var defaultValueAttribute = customAttributes.OfType <DefaultValueAttribute>().FirstOrDefault();
                if (defaultValueAttribute != null)
                {
                    var defaultAsJson = dataContract.JsonConverter(defaultValueAttribute.Value);
                    schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson);
                }

                var obsoleteAttribute = customAttributes.OfType <ObsoleteAttribute>().FirstOrDefault();
                if (obsoleteAttribute != null)
                {
                    schema.Deprecated = true;
                }

                schema.ApplyValidationAttributes(customAttributes);

                ApplyFilters(schema, memberType, schemaRepository, memberInfo: memberInfo);
            }

            return(schema);
        }
        public void CreateFromJson_SimpleType(string json, Type expectedType, object expectedValue)
        {
            var openApiAnyObject = OpenApiAnyFactory.CreateFromJson(json);

            Assert.NotNull(openApiAnyObject);
            Assert.Equal(expectedType, openApiAnyObject.GetType());
            Assert.Equal(AnyType.Primitive, openApiAnyObject.AnyType);
            var valueProperty = expectedType.GetProperty("Value");
            var actualValue   = valueProperty.GetValue(openApiAnyObject);

            Assert.Equal(expectedValue, actualValue);
        }
Esempio n. 9
0
        /// <summary>
        /// Applies the filter to the specified operation using the given context.
        /// </summary>
        /// <param name="operation">The operation to apply the filter to.</param>
        /// <param name="context">The current operation filter context.</param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation is null)
            {
                throw new System.ArgumentNullException(nameof(operation));
            }
            if (context is null)
            {
                throw new System.ArgumentNullException(nameof(context));
            }

            var apiDescription = context.ApiDescription;

            operation.Deprecated |= apiDescription.IsDeprecated();

            foreach (var responseType in context.ApiDescription.SupportedResponseTypes)
            {
                var responseKey = responseType.IsDefaultResponse ? "default" : responseType.StatusCode.ToString();
                var response    = operation.Responses[responseKey];

                foreach (var contentType in response.Content.Keys)
                {
                    if (!responseType.ApiResponseFormats.Any(x => x.MediaType == contentType))
                    {
                        response.Content.Remove(contentType);
                    }
                }
            }

            if (operation.Parameters == null)
            {
                return;
            }

            foreach (var parameter in operation.Parameters)
            {
                var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);

                if (parameter.Description == null)
                {
                    parameter.Description = description.ModelMetadata?.Description;
                }

                if (parameter.Schema.Default == null && description.DefaultValue != null)
                {
                    var json = JsonSerializer.Serialize(description.DefaultValue, description.ModelMetadata.ModelType);
                    parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json);
                }

                parameter.Required |= description.IsRequired;
            }
        }
Esempio n. 10
0
        public void CreateFromJson_NullType()
        {
            var expectedType = typeof(OpenApiNull);

            var openApiAnyObject = OpenApiAnyFactory.CreateFromJson("null");

            Assert.NotNull(openApiAnyObject);
            Assert.Equal(expectedType, openApiAnyObject.GetType());
            Assert.Equal(AnyType.Null, openApiAnyObject.AnyType);
            var valueProperty = expectedType.GetProperty("Value");

            Assert.Null(valueProperty);
        }
Esempio n. 11
0
        /// <summary>
        /// Applies the filter to the specified operation using the given context.
        /// </summary>
        /// <param name="operation">The operation to apply the filter to.</param>
        /// <param name="context">The current operation filter context.</param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            EnsureArg.IsNotNull(operation, nameof(operation));
            EnsureArg.IsNotNull(context, nameof(context));

            ApiDescription apiDescription = context.ApiDescription;

            operation.Deprecated |= apiDescription.IsDeprecated();

            // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1752#issue-663991077
            foreach (ApiResponseType responseType in context.ApiDescription.SupportedResponseTypes)
            {
                // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/b7cf75e7905050305b115dd96640ddd6e74c7ac9/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs#L383-L387
                string          responseKey = responseType.IsDefaultResponse ? "default" : responseType.StatusCode.ToString();
                OpenApiResponse response    = operation.Responses[responseKey];

                foreach (string contentType in response.Content.Keys)
                {
                    if (!responseType.ApiResponseFormats.Any(x => x.MediaType == contentType))
                    {
                        response.Content.Remove(contentType);
                    }
                }

                operation.Responses[responseKey] = response;
            }

            if (operation.Parameters == null)
            {
                return;
            }

            foreach (OpenApiParameter parameter in operation.Parameters)
            {
                ApiParameterDescription description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);

                if (parameter.Description == null)
                {
                    parameter.Description = description.ModelMetadata?.Description;
                }

                if (parameter.Schema.Default == null && description.DefaultValue != null)
                {
                    // REF: https://github.com/Microsoft/aspnet-api-versioning/issues/429#issuecomment-605402330
                    string json = JsonSerializer.Serialize(description.DefaultValue, description.ModelMetadata.ModelType);
                    parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json);
                }

                parameter.Required |= description.IsRequired;
            }
        }
        /// <summary>
        /// Applies the filter to the specified operation using the given context.
        /// </summary>
        /// <param name="operation">The operation to apply the filter to.</param>
        /// <param name="context">The current operation filter context.</param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var apiDescription = context.ApiDescription;

            //operation.Deprecated |= apiDescription.IsDeprecated();

            if (operation.Parameters == null)
            {
                return;
            }

            // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412
            // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413
            foreach (var parameter in operation.Parameters)
            {
                var description = apiDescription.ParameterDescriptions.FirstOrDefault(p => p.Name == parameter.Name);

                if (description == null)
                {
                    continue;
                }

                var routeInfo = description.RouteInfo;

                if (parameter.Description == null)
                {
                    parameter.Description = description.ModelMetadata?.Description;
                }

                if (routeInfo == null)
                {
                    continue;
                }

                if (parameter.Schema.Default == null)
                {
#if NET6_0_OR_GREATER
                    var json = JsonSerializer.Serialize(routeInfo.DefaultValue, description.ModelMetadata.ModelType);
                    parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json);
#else
                    parameter.Schema.Default = OpenApiAnyFactory.CreateFor(parameter.Schema, routeInfo.DefaultValue);
#endif
                }

                //parameter.Required |= description.IsRequired;
                parameter.Required |= !routeInfo.IsOptional;
            }
        }
        private OpenApiSchema GenerateSchemaForParameter(
            Type modelType,
            SchemaRepository schemaRepository,
            ParameterInfo parameterInfo,
            ApiParameterRouteInfo routeInfo)
        {
            var dataContract = GetDataContractFor(modelType);

            var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, parameterInfo, out var knownTypesDataContracts)
                ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts, parameterInfo)
                : GenerateConcreteSchema(dataContract, schemaRepository, parameterInfo);

            if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null)
            {
                schema.AllOf = new[] { new OpenApiSchema {
                                           Reference = schema.Reference
                                       } };
                schema.Reference = null;
            }

            if (schema.Reference == null)
            {
                var customAttributes = parameterInfo.GetCustomAttributes();

                var defaultValue = parameterInfo.HasDefaultValue
                    ? parameterInfo.DefaultValue
                    : customAttributes.OfType <DefaultValueAttribute>().FirstOrDefault()?.Value;

                if (defaultValue != null)
                {
                    var defaultAsJson = dataContract.JsonConverter(defaultValue);
                    schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson);
                }

                schema.ApplyValidationAttributes(customAttributes);
                if (routeInfo != null)
                {
                    schema.ApplyRouteConstraints(routeInfo);
                }

                ApplyFilters(schema, modelType, schemaRepository, parameterInfo: parameterInfo);
            }

            return(schema);
        }
        public void CreateFromJson_Array(string json, Type expectedType, params object[] expectedValues)
        {
            var openApiAnyObject = OpenApiAnyFactory.CreateFromJson(json);

            Assert.NotNull(openApiAnyObject);
            Assert.Equal(typeof(OpenApiArray), openApiAnyObject.GetType());
            Assert.Equal(AnyType.Array, openApiAnyObject.AnyType);
            var array = (OpenApiArray)openApiAnyObject;

            for (var i = 0; i < array.Count; i++)
            {
                Assert.NotNull(array[i]);
                Assert.Equal(expectedType, array[i].GetType());
                if (expectedValues.Length > 0)
                {
                    var valueProperty = expectedType.GetProperty("Value");
                    var expectedValue = expectedValues[i];
                    var actualValue   = valueProperty.GetValue(array[i]);
                    Assert.Equal(expectedValue, actualValue);
                }
            }
        }
Esempio n. 15
0
        private void ApplyParamTags(OpenApiParameter parameter, ParameterFilterContext context)
        {
            if (!(context.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='{context.ParameterInfo.Name}']");

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

                var example = paramNode.GetAttribute("example", "");
                if (!string.IsNullOrEmpty(example))
                {
                    var exampleAsJson = (parameter.Schema?.ResolveType(context.SchemaRepository) == "string")
                        ? $"\"{example}\""
                        : example;

                    parameter.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson);
                }
            }
        }
        /// <summary>
        ///     Applies the filter to the specified operation using the given context.
        /// </summary>
        /// <param name="operation">The operation to apply the filter to.</param>
        /// <param name="context">The current operation filter context.</param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var apiDescription = context.ApiDescription;
            var apiVersion     = apiDescription.GetApiVersion();
            var model          = apiDescription.ActionDescriptor.GetApiVersionModel(ApiVersionMapping.Explicit |
                                                                                    ApiVersionMapping.Implicit);

            operation.Deprecated = model.DeprecatedApiVersions.Contains(apiVersion);

            if (operation.Parameters == null)
            {
                return;
            }

            // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412
            // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413
            foreach (var parameter in operation.Parameters)
            {
                var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);

                if (parameter.Description == null)
                {
                    parameter.Description = description.ModelMetadata?.Description;
                }


                if (parameter.Schema.Default == null && description.DefaultValue != null)
                {
                    // REF: https://github.com/Microsoft/aspnet-api-versioning/issues/429#issuecomment-605402330
                    var json = JsonSerializer.Serialize(description.DefaultValue, description.ModelMetadata.ModelType);
                    parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json);
                }

                parameter.Required |= description.IsRequired;
            }
        }
        public void CreateFromJson_Object()
        {
            var json = JsonSerializer.Serialize(new
            {
                int_value    = 1,
                long_value   = 4294877294L,
                float_value  = 1.5f,
                double_value = 1.5e308,
                string_value = "abc",
                true_value   = true,
                false_value  = false,
                array_value  = new[] { 1, 2 },
                object_value = new
                {
                    a = 1,
                    b = 2
                }
            });

            var openApiAnyObject = OpenApiAnyFactory.CreateFromJson(json);

            Assert.NotNull(openApiAnyObject);
            Assert.Equal(typeof(OpenApiObject), openApiAnyObject.GetType());
            Assert.Equal(AnyType.Object, openApiAnyObject.AnyType);
            var obj = (OpenApiObject)openApiAnyObject;

            Assert.NotNull(obj["int_value"]);
            Assert.Equal(typeof(OpenApiInteger), obj["int_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["int_value"].AnyType);
            Assert.Equal(1, ((OpenApiInteger)obj["int_value"]).Value);

            Assert.NotNull(obj["long_value"]);
            Assert.Equal(typeof(OpenApiLong), obj["long_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["long_value"].AnyType);
            Assert.Equal(4294877294L, ((OpenApiLong)obj["long_value"]).Value);

            Assert.NotNull(obj["float_value"]);
            Assert.Equal(typeof(OpenApiFloat), obj["float_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["float_value"].AnyType);
            Assert.Equal(1.5f, ((OpenApiFloat)obj["float_value"]).Value);

            Assert.NotNull(obj["double_value"]);
            Assert.Equal(typeof(OpenApiDouble), obj["double_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["double_value"].AnyType);
            Assert.Equal(1.5e308, ((OpenApiDouble)obj["double_value"]).Value);

            Assert.NotNull(obj["string_value"]);
            Assert.Equal(typeof(OpenApiString), obj["string_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["string_value"].AnyType);
            Assert.Equal("abc", ((OpenApiString)obj["string_value"]).Value);

            Assert.NotNull(obj["true_value"]);
            Assert.Equal(typeof(OpenApiBoolean), obj["true_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["true_value"].AnyType);
            Assert.True(((OpenApiBoolean)obj["true_value"]).Value);

            Assert.NotNull(obj["false_value"]);
            Assert.Equal(typeof(OpenApiBoolean), obj["false_value"].GetType());
            Assert.Equal(AnyType.Primitive, obj["false_value"].AnyType);
            Assert.False(((OpenApiBoolean)obj["false_value"]).Value);

            Assert.NotNull(obj["array_value"]);
            Assert.Equal(typeof(OpenApiArray), obj["array_value"].GetType());
            Assert.Equal(AnyType.Array, obj["array_value"].AnyType);

            Assert.NotNull(obj["object_value"]);
            Assert.Equal(typeof(OpenApiObject), obj["object_value"].GetType());
            Assert.Equal(AnyType.Object, obj["object_value"].AnyType);
        }
        private OpenApiSchema GenerateSchemaForMember(
            Type modelType,
            SchemaRepository schemaRepository,
            MemberInfo memberInfo,
            ParameterInfo parameterInfo,
            DataProperty dataProperty = null)
        {
            var dataContract = GetDataContractFor(modelType);

            var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, parameterInfo, out var knownTypesDataContracts)
                ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts, parameterInfo)
                : GenerateConcreteSchema(dataContract, schemaRepository, parameterInfo);

            if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null)
            {
                schema.AllOf = new[] { new OpenApiSchema {
                                           Reference = schema.Reference
                                       } };
                schema.Reference = null;
            }

            if (schema.Reference == null)
            {
                var customAttributes = memberInfo.GetInlineAndMetadataAttributes();

                // Nullable, ReadOnly & WriteOnly are only relevant for Schema "properties" (i.e. where dataProperty is non-null)
                if (dataProperty != null)
                {
                    schema.Nullable = _generatorOptions.SupportNonNullableReferenceTypes
                        ? dataProperty.IsNullable && !customAttributes.OfType <RequiredAttribute>().Any() && !memberInfo.IsNonNullableReferenceType()
                        : dataProperty.IsNullable && !customAttributes.OfType <RequiredAttribute>().Any();

                    schema.ReadOnly  = dataProperty.IsReadOnly;
                    schema.WriteOnly = dataProperty.IsWriteOnly;
                }

                var defaultValueAttribute = customAttributes.OfType <DefaultValueAttribute>().FirstOrDefault();
                if (defaultValueAttribute != null)
                {
                    var defaultAsJson = dataContract.JsonConverter(defaultValueAttribute.Value);
                    schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson);
                }

                var obsoleteAttribute = customAttributes.OfType <ObsoleteAttribute>().FirstOrDefault();
                if (obsoleteAttribute != null)
                {
                    schema.Deprecated = true;
                }

                // NullableAttribute behaves diffrently for Dictionaries
                if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    schema.AdditionalProperties.Nullable = !memberInfo.IsDictionaryValueNonNullable();
                }

                schema.ApplyValidationAttributes(customAttributes);

                ApplyFilters(schema, modelType, schemaRepository, memberInfo: memberInfo);
            }

            return(schema);
        }