<PackageReference Include="NJsonSchema" Version="1.13.5811.23634" />

JsonSchemaGenerator

public class JsonSchemaGenerator
Generates a JsonSchema4 object for a given type.
using NJsonSchema.Infrastructure; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace NJsonSchema { public class JsonSchemaGenerator { public JsonSchemaGeneratorSettings Settings { get; set; } public JsonSchemaGenerator(JsonSchemaGeneratorSettings settings) { Settings = settings; } public JsonSchema4 Generate(Type type, ISchemaResolver schemaResolver) { return Generate<JsonSchema4>(type, schemaResolver); } public TSchemaType Generate<TSchemaType>(Type type, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new { TSchemaType val = new TSchemaType(); JsonObjectTypeDescription jsonObjectTypeDescription = JsonObjectTypeDescription.FromType(type); val.Type = jsonObjectTypeDescription.Type; val.Format = jsonObjectTypeDescription.Format; if (val.Type.HasFlag(JsonObjectType.Object)) { if (jsonObjectTypeDescription.IsDictionary) GenerateDictionary(type, val, schemaResolver); else { if ((object)type == typeof(object)) { TSchemaType val2 = new TSchemaType(); val2.Type = JsonObjectType.Object; val2.AllowAdditionalProperties = false; return val2; } val.TypeName = GetTypeName(type); if (schemaResolver.HasSchema(type)) { val.SchemaReference = schemaResolver.GetSchema(type); return val; } val.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes()); GenerateObject(type, val, schemaResolver); } } else if (val.Type.HasFlag(JsonObjectType.Array)) { val.Type = JsonObjectType.Array; Type type2 = (type.GenericTypeArguments.Length == 0) ? type.GetElementType() : type.GenericTypeArguments[0]; if ((object)type2 == null) throw new InvalidOperationException("Could not find item type of enumeration type '" + type.FullName + "'."); val.Item = Generate<JsonSchema4>(type2, schemaResolver); } else if (type.GetTypeInfo().get_IsEnum()) { if (schemaResolver.HasSchema(type)) { val.SchemaReference = schemaResolver.GetSchema(type); return val; } dynamic val3 = type.GetTypeInfo().GetCustomAttributes().SingleOrDefault((Attribute a) => a.GetType().get_Name() == "JsonConverterAttribute"); if (val3 != null) { if (((Type)val3.ConverterType).get_Name() == "StringEnumConverter") LoadEnumerations(type, val); else if (Settings.DefaultEnumHandling == EnumHandling.String) { LoadEnumerations(type, val); } } else if (Settings.DefaultEnumHandling == EnumHandling.String) { LoadEnumerations(type, val); } val.TypeName = type.get_Name(); schemaResolver.AddSchema(type, val); } return val; } private static string GetTypeName(Type type) { if (type.IsConstructedGenericType) return type.get_Name().Split(new char[1] { '`' }).First() + type.GenericTypeArguments[0].get_Name(); return type.get_Name(); } private void GenerateDictionary<TSchemaType>(Type type, TSchemaType schema, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new { if (type.GenericTypeArguments.Length != 2) throw new InvalidOperationException("Could not find value type of dictionary type '" + type.FullName + "'."); Type type2 = type.GenericTypeArguments[1]; schema.AdditionalPropertiesSchema = Generate<JsonProperty>(type2, schemaResolver); schema.AllowAdditionalProperties = true; } protected virtual void GenerateObject<TSchemaType>(Type type, TSchemaType schema, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new { schemaResolver.AddSchema(type, schema); schema.AllowAdditionalProperties = false; string[] properties = GetTypeProperties(type); IEnumerable<PropertyInfo> declaredProperties = type.GetTypeInfo().DeclaredProperties; <>c__DisplayClass9_0<TSchemaType> <>c__DisplayClass9_; object func = <>c__DisplayClass9_.<>9__0; if (func == null) { Func<PropertyInfo, bool> func2; func = (func2 = delegate(PropertyInfo p) { if (properties != null) return Enumerable.Contains<string>((IEnumerable<string>)properties, p.Name); return true; }); } foreach (PropertyInfo item in declaredProperties.Where((Func<PropertyInfo, bool>)func)) { LoadProperty(item, schema, schemaResolver); } GenerateInheritance(type, schema, schemaResolver); } private void GenerateInheritance(Type type, JsonSchema4 schema, ISchemaResolver schemaResolver) { Type baseType = type.GetTypeInfo().get_BaseType(); if ((object)baseType != null && (object)baseType != typeof(object)) { JsonProperty item = Generate<JsonProperty>(baseType, schemaResolver); schema.AllOf.Add(item); } } protected virtual string[] GetTypeProperties(Type type) { if ((object)type == typeof(Exception)) return new string[4] { "InnerException", "Message", "Source", "StackTrace" }; return null; } private void LoadEnumerations<TSchemaType>(Type type, TSchemaType schema) where TSchemaType : JsonSchema4, new { schema.Type = JsonObjectType.String; string[] names = Enum.GetNames(type); foreach (string item in names) { schema.Enumeration.Add((object)item); } } private void LoadProperty<TSchemaType>(PropertyInfo property, TSchemaType parentSchema, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new { Type propertyType = property.PropertyType; JsonObjectTypeDescription jsonObjectTypeDescription = JsonObjectTypeDescription.FromType(propertyType); Attribute[] attributes = property.GetCustomAttributes().ToArray(); JsonProperty jsonProperty = Generate<JsonProperty>(propertyType, schemaResolver); string propertyName = JsonPathUtilities.GetPropertyName(property); parentSchema.Properties.Add(propertyName, jsonProperty); Attribute attribute = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RequiredAttribute"); if (jsonObjectTypeDescription.IsAlwaysRequired || attribute != null) parentSchema.RequiredProperties.Add(property.Name); jsonProperty.Description = GetDescription(property, attributes); dynamic val = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RegularExpressionAttribute"); if (val != null) jsonProperty.Pattern = (string)val.Pattern; dynamic val2 = TryGetAttribute(attributes, "System.ComponentModel.DataAnnotations.RangeAttribute"); if (val2 != null) { if (val2.Minimum != null) jsonProperty.Minimum = (double?)val2.Minimum; if (val2.Maximum != null) jsonProperty.Maximum = (double?)val2.Maximum; } } private string GetDescription(MemberInfo memberInfo, IEnumerable<Attribute> attributes) { dynamic val = TryGetAttribute(attributes, "System.ComponentModel.DescriptionAttribute"); if (val != null) return (string)val.Description; string xmlDocumentation = memberInfo.GetXmlDocumentation(); if (xmlDocumentation != string.Empty) return xmlDocumentation; return null; } private Attribute TryGetAttribute(IEnumerable<Attribute> attributes, string attributeType) { return attributes.FirstOrDefault((Attribute a) => a.GetType().FullName == attributeType); } } }