Exemplo n.º 1
0
        private OpenApiParameter GenerateParameter(
            ApiParameterDescription apiParameter,
            SchemaRepository schemaRepository)
        {
            var name = _options.DescribeAllParametersInCamelCase
                ? apiParameter.Name.ToCamelCase()
                : apiParameter.Name;

            var location = (apiParameter.Source != null && ParameterLocationMap.ContainsKey(apiParameter.Source))
                ? ParameterLocationMap[apiParameter.Source]
                : ParameterLocation.Query;

            var isRequired = (apiParameter.IsFromPath()) ||
                             apiParameter.CustomAttributes().Any(attr => RequiredAttributeTypes.Contains(attr.GetType()));

            var schema = (apiParameter.ModelMetadata != null)
                ? _schemaGenerator.GenerateSchema(apiParameter.ModelMetadata.ModelType, schemaRepository)
                : new OpenApiSchema {
                Type = "string"
            };

            // If it's NOT a reference schema, apply contextual metadata (i.e. from custom attributes)
            if (schema.Reference == null)
            {
                // Honor default value for optional action parameters
                var parameterInfo = apiParameter.ParameterInfo();
                if (parameterInfo != null && parameterInfo.HasDefaultValue)
                {
                    schema.Default = OpenApiAnyFactory.TryCreateFor(schema, parameterInfo.DefaultValue, out IOpenApiAny openApiAny)
                        ? openApiAny
                        : null;
                }

                schema.ApplyCustomAttributes(apiParameter.CustomAttributes());
            }

            var parameter = new OpenApiParameter
            {
                Name     = name,
                In       = location,
                Required = isRequired,
                Schema   = schema
            };

            var filterContext = new ParameterFilterContext(
                apiParameter,
                _schemaGenerator,
                schemaRepository,
                apiParameter.ParameterInfo(),
                apiParameter.PropertyInfo());

            foreach (var filter in _options.ParameterFilters)
            {
                filter.Apply(parameter, filterContext);
            }

            return(parameter);
        }
        public static void ApplyCustomAttributes(this OpenApiSchema schema, IEnumerable <object> memberAttributes)
        {
            foreach (var attribute in memberAttributes)
            {
                if (attribute is DefaultValueAttribute defaultValue)
                {
                    schema.Default = OpenApiAnyFactory.TryCreateFor(schema, defaultValue.Value, out IOpenApiAny openApiAny)
                        ? openApiAny
                        : schema.Default;
                }
                else if (attribute is RegularExpressionAttribute regex)
                {
                    schema.Pattern = regex.Pattern;
                }
                else if (attribute is RangeAttribute range)
                {
                    schema.Maximum = decimal.TryParse(range.Maximum.ToString(), out decimal maximum)
                        ? maximum
                        : schema.Maximum;

                    schema.Minimum = decimal.TryParse(range.Minimum.ToString(), out decimal minimum)
                        ? minimum
                        : schema.Minimum;
                }
                else if (attribute is MinLengthAttribute minLength)
                {
                    schema.MinLength = minLength.Length;
                }
                else if (attribute is MaxLengthAttribute maxLength)
                {
                    schema.MaxLength = maxLength.Length;
                }
                else if (attribute is StringLengthAttribute stringLength)
                {
                    schema.MinLength = stringLength.MinimumLength;
                    schema.MaxLength = stringLength.MaximumLength;
                }
                else if (attribute is EmailAddressAttribute)
                {
                    schema.Format = "email";
                }
                else if (attribute is CreditCardAttribute)
                {
                    schema.Format = "credit-card";
                }
                else if (attribute is PhoneAttribute)
                {
                    schema.Format = "tel";
                }
                else if (attribute is DataTypeAttribute dataTypeAttribute && schema.Type == "string")
                {
                    schema.Format = DataTypeFormatMap.TryGetValue(dataTypeAttribute.DataType, out string format)
                        ? format
                        : schema.Format;
                }
            }
        }
        private OpenApiSchema GeneratePropertySchema(
            JsonProperty jsonProperty,
            MemberInfo memberInfo,
            object[] attributes,
            SchemaRepository schemaRepository)
        {
            var schema = RootGenerator.GenerateSchema(jsonProperty.PropertyType, schemaRepository);

            schema.WriteOnly = jsonProperty.Writable && !jsonProperty.Readable;
            schema.ReadOnly  = jsonProperty.Readable && !jsonProperty.Writable;

            foreach (var attribute in attributes)
            {
                if (attribute is DefaultValueAttribute defaultValue)
                {
                    schema.Default = OpenApiAnyFactory.TryCreateFor(schema, defaultValue.Value, out IOpenApiAny openApiAny)
                        ? openApiAny
                        : schema.Default;
                }
                else if (attribute is RegularExpressionAttribute regex)
                {
                    schema.Pattern = regex.Pattern;
                }
                else if (attribute is RangeAttribute range)
                {
                    schema.Maximum = decimal.TryParse(range.Maximum.ToString(), out decimal maximum)
                        ? maximum
                        : schema.Maximum;

                    schema.Minimum = decimal.TryParse(range.Minimum.ToString(), out decimal minimum)
                        ? minimum
                        : schema.Minimum;
                }
                else if (attribute is MinLengthAttribute minLength)
                {
                    schema.MinLength = minLength.Length;
                }
                else if (attribute is MaxLengthAttribute maxLength)
                {
                    schema.MaxLength = maxLength.Length;
                }
                else if (attribute is StringLengthAttribute stringLength)
                {
                    schema.MinLength = stringLength.MinimumLength;
                    schema.MaxLength = stringLength.MaximumLength;
                }
                else if (attribute is DataTypeAttribute dataTypeAttribute && schema.Type == "string")
                {
                    schema.Format = DataTypeFormatMap.TryGetValue(dataTypeAttribute.DataType, out string format)
                        ? format
                        : schema.Format;
                }
            }

            return(schema);
        }
 public static void ApplyCustomAttributes(this OpenApiSchema schema, IEnumerable <object> customAttributes)
 {
     foreach (var attribute in customAttributes)
     {
         if (attribute is DefaultValueAttribute defaultValue && defaultValue.Value != null)
         {
             schema.Default = OpenApiAnyFactory.TryCreateFor(schema, defaultValue.Value, out IOpenApiAny openApiAny)
                 ? openApiAny
                 : schema.Default;
         }
        private OpenApiParameter GenerateParameter(
            ApiDescription apiDescription,
            ApiParameterDescription apiParameter,
            SchemaRepository schemaRepository)
        {
            apiParameter.GetAdditionalMetadata(
                apiDescription,
                out ParameterInfo parameterInfo,
                out PropertyInfo propertyInfo,
                out IEnumerable <object> parameterOrPropertyAttributes);

            var name = _options.DescribeAllParametersInCamelCase
                ? apiParameter.Name.ToCamelCase()
                : apiParameter.Name;

            var location = ParameterLocationMap.ContainsKey(apiParameter.Source)
                ? ParameterLocationMap[apiParameter.Source]
                : ParameterLocation.Query;

            var isRequired = (apiParameter.IsFromPath()) ||
                             parameterOrPropertyAttributes.Any(attr => RequiredAttributeTypes.Contains(attr.GetType()));

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

            var schema = (apiParameter.ModelMetadata != null)
                ? _schemaGenerator.GenerateSchema(apiParameter.Type, schemaRepository)
                : new OpenApiSchema {
                Type = "string"
            };

            if (defaultValue != null && schema.Reference == null)
            {
                schema.Default = OpenApiAnyFactory.TryCreateFor(schema, defaultValue, out IOpenApiAny openApiAny)
                    ? openApiAny
                    : null;
            }

            var parameter = new OpenApiParameter
            {
                Name     = name,
                In       = location,
                Required = isRequired,
                Schema   = schema
            };

            var filterContext = new ParameterFilterContext(apiParameter, _schemaGenerator, schemaRepository, parameterInfo, propertyInfo);

            foreach (var filter in _options.ParameterFilters)
            {
                filter.Apply(parameter, filterContext);
            }

            return(parameter);
        }
        private OpenApiParameter GenerateParameter(
            ApiParameterDescription apiParameter,
            SchemaRepository schemaRepository)
        {
            var name = _options.DescribeAllParametersInCamelCase
                ? apiParameter.Name.ToCamelCase()
                : apiParameter.Name;

            var location = ParameterLocationMap.ContainsKey(apiParameter.Source)
                ? ParameterLocationMap[apiParameter.Source]
                : ParameterLocation.Query;

            var isRequired = (apiParameter.IsFromPath()) ||
                             apiParameter.CustomAttributes().Any(attr => RequiredAttributeTypes.Contains(attr.GetType()));

            var schema = (apiParameter.ModelMetadata != null)
                ? _schemaGenerator.GenerateSchema(apiParameter.ModelMetadata.ModelType, schemaRepository)
                : new OpenApiSchema {
                Type = "string"
            };

            var defaultValue = apiParameter.CustomAttributes().OfType <DefaultValueAttribute>().FirstOrDefault()?.Value
                               ?? apiParameter.ParameterInfo()?.DefaultValue;

            // NOTE: Oddly, ParameterInfo.DefaultValue returns DBNull if not optional, hence the additional check below
            if (schema.Reference == null && defaultValue != null && defaultValue != DBNull.Value)
            {
                schema.Default = OpenApiAnyFactory.TryCreateFor(schema, defaultValue, out IOpenApiAny openApiAny)
                    ? openApiAny
                    : null;
            }

            var parameter = new OpenApiParameter
            {
                Name     = name,
                In       = location,
                Required = isRequired,
                Schema   = schema
            };

            var filterContext = new ParameterFilterContext(
                apiParameter,
                _schemaGenerator,
                schemaRepository,
                apiParameter.ParameterInfo(),
                apiParameter.PropertyInfo());

            foreach (var filter in _options.ParameterFilters)
            {
                filter.Apply(parameter, filterContext);
            }

            return(parameter);
        }
        private OpenApiSchema GenerateEnumSchema(ApiPrimitive apiPrimitive)
        {
            var schema = apiPrimitive.IsStringEnum
                ? PrimitiveTypeMap[typeof(string)]()
                : PrimitiveTypeMap[apiPrimitive.Type.GetEnumUnderlyingType()]();

            schema.Enum = apiPrimitive.ApiEnumValues
                          .Select(value =>
            {
                return(OpenApiAnyFactory.TryCreateFor(schema, value, out IOpenApiAny openApiAny) ? openApiAny : null);
            })
                          .ToList();

            return(schema);
        }
        private static IOpenApiAny ConvertToOpenApiType(Type memberType, OpenApiSchema schema, string stringValue)
        {
            object typedValue;

            try
            {
                typedValue = TypeDescriptor.GetConverter(memberType).ConvertFromInvariantString(stringValue);
            }
            catch (Exception)
            {
                return(null);
            }

            return(OpenApiAnyFactory.TryCreateFor(schema, typedValue, out IOpenApiAny openApiAny)
                ? openApiAny
                : null);
        }
        private OpenApiSchema GenerateSchemaFromFormParameters(
            IEnumerable <ApiParameterDescription> formParameters,
            SchemaRepository schemaRepository)
        {
            var properties            = new Dictionary <string, OpenApiSchema>();
            var requiredPropertyNames = new List <string>();

            foreach (var formParameter in formParameters)
            {
                var name = _options.DescribeAllParametersInCamelCase
                    ? formParameter.Name.ToCamelCase()
                    : formParameter.Name;

                var schema = (formParameter.ModelMetadata != null)
                    ? _schemaGenerator.GenerateSchema(formParameter.ModelMetadata.ModelType, schemaRepository)
                    : new OpenApiSchema {
                    Type = "string"
                };

                var defaultValue = formParameter.CustomAttributes().OfType <DefaultValueAttribute>().FirstOrDefault()?.Value
                                   ?? formParameter.ParameterInfo()?.DefaultValue;

                // NOTE: Oddly, ParameterInfo.DefaultValue returns DBNull if not optional, hence the additional check below
                if (schema.Reference == null && defaultValue != null && defaultValue != DBNull.Value)
                {
                    schema.Default = OpenApiAnyFactory.TryCreateFor(schema, defaultValue, out IOpenApiAny openApiAny)
                        ? openApiAny
                        : null;
                }

                properties.Add(name, schema);

                if (formParameter.IsFromPath() || formParameter.CustomAttributes().Any(attr => RequiredAttributeTypes.Contains(attr.GetType())))
                {
                    requiredPropertyNames.Add(name);
                }
            }

            return(new OpenApiSchema
            {
                Type = "object",
                Properties = properties,
                Required = new SortedSet <string>(requiredPropertyNames)
            });
        }
        private OpenApiSchema GenerateEnumSchema(JsonPrimitiveContract jsonPrimitiveContract)
        {
            var stringEnumConverter = (jsonPrimitiveContract.Converter as StringEnumConverter)
                                      ?? _serializerSettings.Converters.OfType <StringEnumConverter>().FirstOrDefault();

            var describeAsString = Options.DescribeAllEnumsAsStrings ||
                                   (stringEnumConverter != null);

            var describeInCamelCase = Options.DescribeStringEnumsInCamelCase ||
                                      (stringEnumConverter != null && stringEnumConverter.CamelCaseText);

            var enumType           = jsonPrimitiveContract.UnderlyingType;
            var enumUnderlyingType = describeAsString ? typeof(string) : enumType.GetEnumUnderlyingType();

            var schema = FactoryMethodMap[enumUnderlyingType]();

            if (describeAsString)
            {
                schema.Enum = enumType.GetEnumNames()
                              .Distinct()
                              .Select(name =>
                {
                    name = describeInCamelCase ? name.ToCamelCase() : name;
                    return((IOpenApiAny)(new OpenApiString(name)));
                })
                              .ToList();
            }
            else
            {
                schema.Enum = enumType.GetEnumValues()
                              .Cast <object>()
                              .Distinct()
                              .Select(value =>
                {
                    value = Convert.ChangeType(value, enumUnderlyingType);
                    return(OpenApiAnyFactory.TryCreateFor(schema, value, out IOpenApiAny openApiAny) ? openApiAny : null);
                })
                              .ToList();
            }

            return(schema);
        }
Exemplo n.º 11
0
        private static IOpenApiAny ConvertToOpenApiType(Type memberType, OpenApiSchema schema, string stringValue)
        {
            object typedValue;
            var    culture = CultureInfo.CurrentCulture;

            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

            try
            {
                typedValue = TypeDescriptor.GetConverter(memberType).ConvertFrom(stringValue);
            }
            catch (Exception)
            {
                return(null);
            }
            finally
            {
                CultureInfo.CurrentCulture = culture;
            }

            return(OpenApiAnyFactory.TryCreateFor(schema, typedValue, out IOpenApiAny openApiAny)
                ? openApiAny
                : null);
        }