public TSchemaType Generate <TSchemaType>(Type type) where TSchemaType : JsonSchema4, new() { var schema = new TSchemaType(); var typeDescription = JsonObjectTypeDescription.FromType(type); schema.Type = typeDescription.Type; schema.Format = typeDescription.Format; if (schema.Type.HasFlag(JsonObjectType.Object)) { schema.Title = type.Name; foreach (var property in type.GetRuntimeProperties()) { LoadProperty(property, schema); } } else if (schema.Type.HasFlag(JsonObjectType.Array)) { schema.Type = JsonObjectType.Array; var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0]; schema.Item = Generate <JsonSchema4>(itemType); } TryLoadEnumerations(type, schema); return(schema); }
/// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary> /// <typeparam name="TSchemaType">The type of the schema type.</typeparam> /// <param name="type">The type.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <returns>The schema.</returns> /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception> /// <exception cref="InvalidOperationException">Could not find item type of enumeration type.</exception> public TSchemaType Generate <TSchemaType>(Type type, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { var schema = new TSchemaType(); var typeDescription = JsonObjectTypeDescription.FromType(type); schema.Type = typeDescription.Type; schema.Format = typeDescription.Format; if (schema.Type.HasFlag(JsonObjectType.Object)) { if (typeDescription.IsDictionary) { GenerateDictionary(type, schema, schemaResolver); } else { if (type == typeof(object)) { return(new TSchemaType { Type = JsonObjectType.Object, AllowAdditionalProperties = false }); } schema.TypeName = GetTypeName(type); if (schemaResolver.HasSchema(type)) { schema.SchemaReference = schemaResolver.GetSchema(type); return(schema); } GenerateObject(type, schema, schemaResolver); GenerateInheritance(type, schema, schemaResolver); } } else if (schema.Type.HasFlag(JsonObjectType.Array)) { schema.Type = JsonObjectType.Array; var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0]; if (itemType == null) { throw new InvalidOperationException("Could not find item type of enumeration type '" + type.FullName + "'."); } schema.Item = Generate <JsonSchema4>(itemType, schemaResolver); } TryLoadEnumerations(type, schema); return(schema); }
private void LoadProperty <TSchemaType>(PropertyInfo property, TSchemaType parentSchema, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { var propertyType = property.PropertyType; var propertyTypeDescription = JsonObjectTypeDescription.FromType(propertyType); var attributes = property.GetCustomAttributes().ToArray(); var jsonProperty = Generate <JsonProperty>(propertyType, schemaResolver); var propertyName = property.Name; var jsonPropertyAttribute = attributes.FirstOrDefault(a => a is JsonPropertyAttribute) as JsonPropertyAttribute; if (jsonPropertyAttribute != null && !string.IsNullOrEmpty(jsonPropertyAttribute.PropertyName)) { propertyName = jsonPropertyAttribute.PropertyName; } parentSchema.Properties.Add(propertyName, jsonProperty); var requiredAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RequiredAttribute"); if (propertyTypeDescription.IsAlwaysRequired || requiredAttribute != null) { parentSchema.RequiredProperties.Add(property.Name); } dynamic descriptionAttribute = TryGetAttribute(attributes, "System.ComponentModel.DescriptionAttribute"); if (descriptionAttribute != null) { jsonProperty.Description = descriptionAttribute.Description; } dynamic regexAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RegularExpressionAttribute"); if (regexAttribute != null) { jsonProperty.Pattern = regexAttribute.Pattern; } dynamic rangeAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RangeAttribute"); if (rangeAttribute != null) { if (rangeAttribute.Minimum != null) { jsonProperty.Minimum = rangeAttribute.Minimum; } if (rangeAttribute.Maximum != null) { jsonProperty.Maximum = rangeAttribute.Maximum; } } }
private void LoadProperty <TSchemaType>(PropertyInfo property, TSchemaType parentSchema, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { var propertyType = property.PropertyType; var propertyTypeDescription = JsonObjectTypeDescription.FromType(propertyType); var attributes = property.GetCustomAttributes().ToArray(); var jsonProperty = Generate <JsonProperty>(propertyType, schemaResolver); var propertyName = JsonPathUtilities.GetPropertyName(property); parentSchema.Properties.Add(propertyName, jsonProperty); var requiredAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RequiredAttribute"); if (propertyTypeDescription.IsAlwaysRequired || requiredAttribute != null) { parentSchema.RequiredProperties.Add(property.Name); } jsonProperty.Description = GetDescription(property, attributes); dynamic regexAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RegularExpressionAttribute"); if (regexAttribute != null) { jsonProperty.Pattern = regexAttribute.Pattern; } dynamic rangeAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RangeAttribute"); if (rangeAttribute != null) { if (rangeAttribute.Minimum != null) { jsonProperty.Minimum = rangeAttribute.Minimum; } if (rangeAttribute.Maximum != null) { jsonProperty.Maximum = rangeAttribute.Maximum; } } }
/// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary> /// <typeparam name="TSchemaType">The type of the schema type.</typeparam> /// <param name="type">The type.</param> /// <param name="parentAttributes">The parent property or parameter attributes.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <returns>The schema.</returns> /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception> /// <exception cref="InvalidOperationException">Could not find item type of array type.</exception> public TSchemaType Generate <TSchemaType>(Type type, IEnumerable <Attribute> parentAttributes, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { var schema = HandleSpecialTypes <TSchemaType>(type); if (schema != null) { return(schema); } schema = new TSchemaType(); var typeDescription = JsonObjectTypeDescription.FromType(type); schema.Type = typeDescription.Type; schema.Format = typeDescription.Format; if (schema.Type.HasFlag(JsonObjectType.Object)) { if (typeDescription.IsDictionary) { GenerateDictionary(type, schema, schemaResolver); } else { schema.TypeName = GetTypeName(type); if (schemaResolver.HasSchema(type, false)) { schema.SchemaReference = schemaResolver.GetSchema(type, false); return(schema); } schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes()); GenerateObject(type, schema, schemaResolver); } } else if (schema.Type.HasFlag(JsonObjectType.Array)) { schema.Type = JsonObjectType.Array; var genericTypeArguments = GetGenericTypeArguments(type); var itemType = genericTypeArguments.Length == 0 ? type.GetElementType() : genericTypeArguments[0]; if (itemType == null) { throw new InvalidOperationException("Could not find item type of array type '" + type.FullName + "'."); } schema.Item = Generate <JsonSchema4>(itemType, schemaResolver); } else if (type.GetTypeInfo().IsEnum) { var isIntegerEnumeration = IsIntegerEnumeration(parentAttributes) || HasStringEnumConverter(type.GetTypeInfo().GetCustomAttributes()); if (schemaResolver.HasSchema(type, isIntegerEnumeration)) { schema.Type = isIntegerEnumeration ? JsonObjectType.Integer : JsonObjectType.String; schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration); return(schema); } LoadEnumerations(type, schema, isIntegerEnumeration, parentAttributes); schema.TypeName = GetTypeName(type); schemaResolver.AddSchema(type, isIntegerEnumeration, schema); } return(schema); }
private void LoadProperty <TSchemaType>(PropertyInfo property, TSchemaType parentSchema, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { var propertyType = property.PropertyType; var propertyTypeDescription = JsonObjectTypeDescription.FromType(propertyType); var attributes = property.GetCustomAttributes().ToArray(); if (attributes.All(a => !(a is JsonIgnoreAttribute))) { var jsonProperty = Generate <JsonProperty>(propertyType, property.GetCustomAttributes(), schemaResolver); var propertyName = JsonPathUtilities.GetPropertyName(property); parentSchema.Properties.Add(propertyName, jsonProperty); var jsonPropertyAttribute = property.GetCustomAttribute <JsonPropertyAttribute>(); var isJsonPropertyRequired = jsonPropertyAttribute != null && jsonPropertyAttribute.Required == Required.Always; var requiredAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RequiredAttribute"); if (propertyTypeDescription.IsAlwaysRequired || requiredAttribute != null || isJsonPropertyRequired) { parentSchema.RequiredProperties.Add(propertyName); } dynamic displayAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.DisplayAttribute"); if (displayAttribute != null && displayAttribute.Name != null) { jsonProperty.Title = displayAttribute.Name; } jsonProperty.Description = GetDescription(property, attributes); dynamic regexAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RegularExpressionAttribute"); if (regexAttribute != null) { jsonProperty.Pattern = regexAttribute.Pattern; } if (propertyTypeDescription.Type == JsonObjectType.Number || propertyTypeDescription.Type == JsonObjectType.Integer) { dynamic rangeAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RangeAttribute"); if (rangeAttribute != null) { if (rangeAttribute.Minimum != null) { jsonProperty.Minimum = rangeAttribute.Minimum; } if (rangeAttribute.Maximum != null) { jsonProperty.Maximum = rangeAttribute.Maximum; } } } dynamic minLengthAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.MinLengthAttribute"); if (minLengthAttribute != null && minLengthAttribute.Length != null) { if (propertyTypeDescription.Type == JsonObjectType.String) { jsonProperty.MinLength = minLengthAttribute.Length; } else if (propertyTypeDescription.Type == JsonObjectType.Array) { jsonProperty.MinItems = minLengthAttribute.Length; } } dynamic maxLengthAttribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.MaxLengthAttribute"); if (maxLengthAttribute != null && maxLengthAttribute.Length != null) { if (propertyTypeDescription.Type == JsonObjectType.String) { jsonProperty.MaxLength = maxLengthAttribute.Length; } else if (propertyTypeDescription.Type == JsonObjectType.Array) { jsonProperty.MaxItems = maxLengthAttribute.Length; } } } }
/// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary> /// <typeparam name="TSchemaType">The type of the schema type.</typeparam> /// <param name="type">The type.</param> /// <param name="schemaResolver">The schema resolver.</param> /// <returns>The schema.</returns> /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception> /// <exception cref="InvalidOperationException">Could not find item type of enumeration type.</exception> public TSchemaType Generate <TSchemaType>(Type type, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { var schema = new TSchemaType(); var typeDescription = JsonObjectTypeDescription.FromType(type); schema.Type = typeDescription.Type; schema.Format = typeDescription.Format; if (schema.Type.HasFlag(JsonObjectType.Object)) { if (typeDescription.IsDictionary) { GenerateDictionary(type, schema, schemaResolver); } else { if (type == typeof(object)) { return(new TSchemaType { Type = JsonObjectType.Object, AllowAdditionalProperties = false }); } schema.TypeName = GetTypeName(type); if (schemaResolver.HasSchema(type)) { schema.SchemaReference = schemaResolver.GetSchema(type); return(schema); } schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes()); GenerateObject(type, schema, schemaResolver); GenerateInheritance(type, schema, schemaResolver); } } else if (schema.Type.HasFlag(JsonObjectType.Array)) { schema.Type = JsonObjectType.Array; var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0]; if (itemType == null) { throw new InvalidOperationException("Could not find item type of enumeration type '" + type.FullName + "'."); } schema.Item = Generate <JsonSchema4>(itemType, schemaResolver); } else if (type.GetTypeInfo().IsEnum) { if (schemaResolver.HasSchema(type)) { schema.SchemaReference = schemaResolver.GetSchema(type); return(schema); } dynamic jsonConverterAttribute = type.GetTypeInfo().GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "JsonConverterAttribute"); if (jsonConverterAttribute != null) { var converterType = (Type)jsonConverterAttribute.ConverterType; if (converterType.Name == "StringEnumConverter") { LoadEnumerations(type, schema); } else if (Settings.DefaultEnumHandling == EnumHandling.String) { LoadEnumerations(type, schema); } } else if (Settings.DefaultEnumHandling == EnumHandling.String) { LoadEnumerations(type, schema); } schema.TypeName = type.Name; schemaResolver.AddSchema(type, schema); } return(schema); }
/// <exception cref="InvalidOperationException">Could not find item type of array type.</exception> private TSchemaType Generate <TSchemaType>(Type type, PropertyInfo propertyInfo, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new() { if (type == typeof(object) || type == typeof(JObject)) { return(new TSchemaType { Type = JsonObjectType.Object, AllowAdditionalProperties = true }); } var schema = new TSchemaType(); var typeDescription = JsonObjectTypeDescription.FromType(type); schema.Type = typeDescription.Type; schema.Format = typeDescription.Format; if (schema.Type.HasFlag(JsonObjectType.Object)) { if (typeDescription.IsDictionary) { GenerateDictionary(type, schema, schemaResolver); } else { schema.TypeName = GetTypeName(type); if (schemaResolver.HasSchema(type, false)) { schema.SchemaReference = schemaResolver.GetSchema(type, false); return(schema); } schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes()); GenerateObject(type, schema, schemaResolver); } } else if (schema.Type.HasFlag(JsonObjectType.Array)) { schema.Type = JsonObjectType.Array; var genericTypeArguments = GetGenericTypeArguments(type); var itemType = genericTypeArguments.Length == 0 ? type.GetElementType() : genericTypeArguments[0]; if (itemType == null) { throw new InvalidOperationException("Could not find item type of array type '" + type.FullName + "'."); } schema.Item = Generate <JsonSchema4>(itemType, schemaResolver); } else if (type.GetTypeInfo().IsEnum) { var isIntegerEnumeration = IsIntegerEnumeration(propertyInfo); if (schemaResolver.HasSchema(type, isIntegerEnumeration)) { schema.Type = isIntegerEnumeration ? JsonObjectType.Integer : JsonObjectType.String; schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration); return(schema); } LoadEnumerations(type, schema, isIntegerEnumeration); schema.TypeName = GetTypeName(type); schemaResolver.AddSchema(type, isIntegerEnumeration, schema); } return(schema); }