private static IOpenApiAny ConvertToOpenApiType(Type memberType, OpenApiSchema schema, string stringValue) { object typedValue; try { typedValue = TypeDescriptor.GetConverter(memberType).ConvertFrom( context: null, culture: CultureInfo.InvariantCulture, stringValue); } catch (Exception) { return(null); } return(OpenApiAnyFactory.CreateFor(schema, typedValue)); }
private OpenApiSchema GeneratePrimitiveSchema(DataContract dataContract) { var schema = new OpenApiSchema { Type = dataContract.DataType.ToString().ToLower(CultureInfo.InvariantCulture), Format = dataContract.DataFormat }; if (dataContract.EnumValues != null) { schema.Enum = dataContract.EnumValues .Distinct() .Select(value => OpenApiAnyFactory.CreateFor(schema, value)) .ToList(); } return(schema); }
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.Type, schemaRepository) : new OpenApiSchema { Type = "string" }; var defaultValue = formParameter.CustomAttributes().OfType <DefaultValueAttribute>().FirstOrDefault()?.Value ?? formParameter.ParameterInfo()?.DefaultValue; if (defaultValue != null && schema.Reference == null) { 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); }
private OpenApiSchema GeneratePrimitiveSchema(DataContract dataContract) { var schema = new OpenApiSchema { Type = dataContract.DataType.ToString().ToLower(CultureInfo.InvariantCulture), Format = dataContract.DataFormat }; if (dataContract.UnderlyingType.IsEnum) { schema.Enum = dataContract.UnderlyingType.GetEnumValues() .Cast <object>() .Distinct() .Select(value => _serializerBehavior.Serialize(value)) .Select(json => OpenApiAnyFactory.CreateFromJson(json)) .ToList(); } return(schema); }
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); } } }
private OpenApiSchema GenerateSchemaForParameter( Type modelType, SchemaRepository schemaRepository, ParameterInfo parameterInfo) { var dataContract = GetDataContractFor(modelType); 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 = 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); ApplyFilters(schema, modelType, schemaRepository, parameterInfo: parameterInfo); } return(schema); }
private void ApplyParameterMetadata(OpenApiSchema schema, Type type, ParameterInfo parameterInfo) { if (schema.Reference != null && _generatorOptions.UseAllOfToExtendReferenceSchemas) { schema.AllOf = new[] { new OpenApiSchema { Reference = schema.Reference } }; schema.Reference = null; } if (schema.Reference == null) { schema.Nullable = type.IsReferenceOrNullableType(); schema.ApplyCustomAttributes(parameterInfo.GetCustomAttributes()); if (parameterInfo.HasDefaultValue) { schema.Default = OpenApiAnyFactory.CreateFor(schema, parameterInfo.DefaultValue); } } }
public override OpenApiSchema CreateDefinitionSchema(Type type, SchemaRepository schemaRepository) { var isNullable = type.IsNullable(out Type innerType); var enumType = isNullable ? innerType : type; //Test to determine if the serializer will treat as string or not var describeAsString = JsonSerializer.Serialize(enumType.GetEnumValues().GetValue(0), _serializerOptions).StartsWith("\""); var schema = describeAsString ? EnumTypeMap[typeof(string)]() : EnumTypeMap[enumType.GetEnumUnderlyingType()](); if (describeAsString) { schema.Enum = enumType.GetEnumValues() .Cast <object>() .Select(value => { var stringValue = JsonSerializer.Serialize(value, _serializerOptions).Replace("\"", string.Empty); return(OpenApiAnyFactory.CreateFor(schema, stringValue)); }) .ToList(); } else { schema.Enum = enumType.GetEnumValues() .Cast <object>() .Select(value => OpenApiAnyFactory.CreateFor(schema, value)) .ToList(); } schema.Nullable = isNullable; return(schema); }
private void ApplyParameterMetadata(OpenApiSchema schema, Type type, ParameterInfo parameterInfo) { if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null) { schema.AllOf = new[] { new OpenApiSchema { Reference = schema.Reference } }; schema.Reference = null; } if (schema.Reference == null) { schema.Nullable = type.IsReferenceOrNullableType(); if (parameterInfo.HasDefaultValue) { var defaultAsJson = _serializerBehavior.Serialize(parameterInfo.DefaultValue); schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson); } schema.ApplyValidationAttributes(parameterInfo.GetCustomAttributes()); } }
private void ApplyMemberMetadata(OpenApiSchema schema, Type type, MemberInfo memberInfo) { 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(); schema.Nullable = type.IsReferenceOrNullableType(); if (!_generatorOptions.SuppressNonNullableReferenceTypes && memberInfo.IsNonNullable()) { schema.Nullable = false; } var defaultValueAttribute = customAttributes.OfType <DefaultValueAttribute>().FirstOrDefault(); if (defaultValueAttribute != null) { var defaultAsJson = _serializerBehavior.Serialize(defaultValueAttribute.Value); schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson); // TODO: address assumption that serializer returns JSON } var obsoleteAttribute = customAttributes.OfType <ObsoleteAttribute>().FirstOrDefault(); if (obsoleteAttribute != null) { schema.Deprecated = true; } schema.ApplyValidationAttributes(customAttributes); } }
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); }
private void ApplyPropertyTags(OpenApiParameter parameter, PropertyInfo propertyInfo) { var propertyMemberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(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) { parameter.Example = OpenApiAnyFactory.CreateFromJson(exampleNode.InnerXml); } }
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 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; } } return(schema); }
private OpenApiSchema GenerateSchemaForMember( Type modelType, SchemaRepository schemaRepository, MemberInfo memberInfo, DataProperty dataProperty = null) { var dataContract = GetDataContractFor(modelType); 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.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); }
private static void ApplyDefaultValueAttribute(OpenApiSchema schema, DefaultValueAttribute defaultValueAttribute) { schema.Default = OpenApiAnyFactory.CreateFor(schema, defaultValueAttribute.Value); }