JsonSchemaGenerator
Generates a JsonSchema4 object for a given type.
using Microsoft.Runtime.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NJsonSchema.Annotations;
using NJsonSchema.Converters;
using NJsonSchema.Generation.TypeMappers;
using NJsonSchema.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace NJsonSchema.Generation
{
public class JsonSchemaGenerator
{
private static readonly Dictionary<string, string> DataTypeFormats = new Dictionary<string, string> {
{
"DateTime",
"date-time"
},
{
"Date",
"date"
},
{
"Time",
"time"
},
{
"EmailAddress",
"email"
},
{
"PhoneNumber",
"phone"
},
{
"Url",
"uri"
}
};
public JsonSchemaGeneratorSettings Settings { get; }
public JsonSchemaGenerator(JsonSchemaGeneratorSettings settings)
{
Settings = settings;
}
public async Task<JsonSchema4> GenerateAsync(Type type)
{
JsonSchema4 schema = new JsonSchema4();
JsonSchemaResolver schemaResolver = new JsonSchemaResolver(schema, Settings);
ConfiguredTaskAwaitable val = AwaitExtensions.ConfigureAwait(GenerateAsync(type, null, schema, schemaResolver), false);
ConfiguredTaskAwaiter val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
val2 = val3;
}
val2.GetResult();
return schema;
}
public Task<JsonSchema4> GenerateAsync(Type type, JsonSchemaResolver schemaResolver)
{
return GenerateAsync<JsonSchema4>(type, schemaResolver);
}
public Task<TSchemaType> GenerateAsync<TSchemaType>(Type type, JsonSchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new
{
return GenerateAsync<TSchemaType>(type, null, schemaResolver);
}
public async Task<JsonSchema4> GenerateAsync(Type type, IEnumerable<Attribute> parentAttributes, JsonSchemaResolver schemaResolver)
{
ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync<JsonSchema4>(type, parentAttributes, schemaResolver), false).GetAwaiter();
if (!val.get_IsCompleted()) {
await val;
ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter);
val = val2;
}
return (JsonSchema4)val.GetResult();
}
public async Task<TSchemaType> GenerateAsync<TSchemaType>(Type type, IEnumerable<Attribute> parentAttributes, JsonSchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new
{
TSchemaType schema = new TSchemaType();
ConfiguredTaskAwaitable val = AwaitExtensions.ConfigureAwait(this.GenerateAsync<TSchemaType>(type, parentAttributes, schema, schemaResolver), false);
ConfiguredTaskAwaiter val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
val2 = val3;
}
val2.GetResult();
return schema;
}
public virtual async Task GenerateAsync<TSchemaType>(Type type, IEnumerable<Attribute> parentAttributes, TSchemaType schema, JsonSchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new
{
TaskAwaiter<bool> val = AwaitExtensions.GetAwaiter<bool>(this.TryHandleSpecialTypesAsync<TSchemaType>(type, schema, schemaResolver, parentAttributes));
if (!val.get_IsCompleted()) {
await val;
TaskAwaiter<bool> val2 = default(TaskAwaiter<bool>);
val = val2;
}
TaskAwaiter val3;
if (val.GetResult()) {
val3 = AwaitExtensions.GetAwaiter(ApplySchemaProcessorsAsync(type, schema, schemaResolver));
if (!val3.get_IsCompleted()) {
await val3;
TaskAwaiter val4 = default(TaskAwaiter);
val3 = val4;
}
val3.GetResult();
} else {
if (schemaResolver.RootObject == schema)
schema.Title = Settings.SchemaNameGenerator.Generate(type);
this.ApplyExtensionDataAttributes<TSchemaType>(type, schema, parentAttributes);
JsonContract contract = ResolveContract(type);
JsonObjectTypeDescription typeDescription = JsonObjectTypeDescription.FromType(type, contract, parentAttributes, Settings.DefaultEnumHandling);
ConfiguredTaskAwaitable<string> val8;
ConfiguredTaskAwaiter val9;
ConfiguredTaskAwaitable<JsonSchema4> val11;
ConfiguredTaskAwaiter val12;
if (typeDescription.Type.HasFlag(JsonObjectType.Object)) {
ConfiguredTaskAwaitable val5;
ConfiguredTaskAwaiter val6;
if (typeDescription.IsDictionary) {
typeDescription.ApplyType(schema);
val5 = AwaitExtensions.ConfigureAwait(this.GenerateDictionaryAsync<TSchemaType>(type, schema, schemaResolver), false);
val6 = val5.GetAwaiter();
if (!val6.get_IsCompleted()) {
await val6;
ConfiguredTaskAwaiter val7 = default(ConfiguredTaskAwaiter);
val6 = val7;
}
val6.GetResult();
} else if (schemaResolver.HasSchema(type, false)) {
schema.SchemaReference = schemaResolver.GetSchema(type, false);
} else if (schema.GetType() == typeof(JsonSchema4)) {
typeDescription.ApplyType(schema);
val8 = AwaitExtensions.ConfigureAwait<string>(ReflectionExtensions.GetTypeInfo(type).GetDescriptionAsync(ReflectionExtensions.GetCustomAttributes(ReflectionExtensions.GetTypeInfo(type), true)), false);
val9 = val8.GetAwaiter();
if (!val9.get_IsCompleted()) {
await val9;
ConfiguredTaskAwaiter val10 = default(ConfiguredTaskAwaiter);
val9 = val10;
}
schema.Description = (string)val9.GetResult();
val5 = AwaitExtensions.ConfigureAwait(this.GenerateObjectAsync<TSchemaType>(type, contract, schema, schemaResolver), false);
val6 = val5.GetAwaiter();
if (!val6.get_IsCompleted()) {
await val6;
ConfiguredTaskAwaiter val7 = default(ConfiguredTaskAwaiter);
val6 = val7;
}
val6.GetResult();
} else {
val11 = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(type, parentAttributes, schemaResolver), false);
val12 = val11.GetAwaiter();
if (!val12.get_IsCompleted()) {
await val12;
ConfiguredTaskAwaiter val13 = default(ConfiguredTaskAwaiter);
val12 = val13;
}
schema.SchemaReference = (JsonSchema4)val12.GetResult();
}
} else if (ReflectionExtensions.GetTypeInfo(type).IsEnum) {
bool isIntegerEnumeration = typeDescription.Type == JsonObjectType.Integer;
if (schemaResolver.HasSchema(type, isIntegerEnumeration))
schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration);
else if (schema.GetType() == typeof(JsonSchema4)) {
LoadEnumerations(type, schema, typeDescription);
typeDescription.ApplyType(schema);
val8 = AwaitExtensions.ConfigureAwait<string>(type.GetXmlSummaryAsync(), false);
val9 = val8.GetAwaiter();
if (!val9.get_IsCompleted()) {
await val9;
ConfiguredTaskAwaiter val10 = default(ConfiguredTaskAwaiter);
val9 = val10;
}
schema.Description = (string)val9.GetResult();
schemaResolver.AddSchema(type, isIntegerEnumeration, schema);
} else {
val11 = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(type, parentAttributes, schemaResolver), false);
val12 = val11.GetAwaiter();
if (!val12.get_IsCompleted()) {
await val12;
ConfiguredTaskAwaiter val13 = default(ConfiguredTaskAwaiter);
val12 = val13;
}
schema.SchemaReference = (JsonSchema4)val12.GetResult();
}
} else if (typeDescription.Type.HasFlag(JsonObjectType.Array)) {
typeDescription.ApplyType(schema);
Type enumerableItemType = type.GetEnumerableItemType();
if (enumerableItemType != (Type)null) {
val11 = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateWithReferenceAsync(schemaResolver, enumerableItemType), false);
val12 = val11.GetAwaiter();
if (!val12.get_IsCompleted()) {
await val12;
ConfiguredTaskAwaiter val13 = default(ConfiguredTaskAwaiter);
val12 = val13;
}
schema.Item = (JsonSchema4)val12.GetResult();
} else
schema.Item = JsonSchema4.CreateAnySchema();
} else {
typeDescription.ApplyType(schema);
}
val3 = AwaitExtensions.GetAwaiter(ApplySchemaProcessorsAsync(type, schema, schemaResolver));
if (!val3.get_IsCompleted()) {
await val3;
TaskAwaiter val4 = default(TaskAwaiter);
val3 = val4;
}
val3.GetResult();
}
}
private async Task ApplySchemaProcessorsAsync(Type type, JsonSchema4 schema, JsonSchemaResolver schemaResolver)
{
SchemaProcessorContext context = new SchemaProcessorContext(type, schema, schemaResolver, this);
foreach (ISchemaProcessor schemaProcessor in Settings.SchemaProcessors) {
TaskAwaiter val = AwaitExtensions.GetAwaiter(schemaProcessor.ProcessAsync(context));
if (!val.get_IsCompleted()) {
await val;
TaskAwaiter val2 = default(TaskAwaiter);
val = val2;
val2 = default(TaskAwaiter);
}
val.GetResult();
}
}
private async Task<JsonSchema4> GenerateWithReferenceAsync(JsonSchemaResolver schemaResolver, Type itemType)
{
ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(itemType, schemaResolver), false).GetAwaiter();
if (!val.get_IsCompleted()) {
await val;
ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter);
val = val2;
}
JsonSchema4 result = (JsonSchema4)val.GetResult();
if (Settings.GenerateXmlObjects)
result.GenerateXmlObjectForItemType(itemType);
if (RequiresSchemaReference(itemType, null))
return new JsonSchema4 {
SchemaReference = result
};
return result;
}
private void ApplyExtensionDataAttributes<TSchemaType>(Type type, TSchemaType schema, IEnumerable<Attribute> parentAttributes) where TSchemaType : JsonSchema4, new
{
if (parentAttributes == null) {
JsonSchemaExtensionDataAttribute[] source = ReflectionExtensions.GetTypeInfo(type).GetCustomAttributes<JsonSchemaExtensionDataAttribute>(true).ToArray();
if (source.Any())
schema.ExtensionData = source.ToDictionary((JsonSchemaExtensionDataAttribute a) => a.Property, (JsonSchemaExtensionDataAttribute a) => a.Value);
} else {
JsonSchemaExtensionDataAttribute[] source2 = parentAttributes.OfType<JsonSchemaExtensionDataAttribute>().ToArray();
if (source2.Any())
schema.ExtensionData = source2.ToDictionary((JsonSchemaExtensionDataAttribute a) => a.Property, (JsonSchemaExtensionDataAttribute a) => a.Value);
}
}
private async Task<bool> TryHandleSpecialTypesAsync<TSchemaType>(Type type, TSchemaType schema, JsonSchemaResolver schemaResolver, IEnumerable<Attribute> parentAttributes) where TSchemaType : JsonSchema4, new
{
ITypeMapper typeMapper = Enumerable.FirstOrDefault<ITypeMapper>((IEnumerable<ITypeMapper>)Settings.TypeMappers, (Func<ITypeMapper, bool>)((ITypeMapper m) => m.MappedType == type));
if (typeMapper == null && ReflectionExtensions.GetTypeInfo(type).IsGenericType) {
Type genericType = type.GetGenericTypeDefinition();
typeMapper = Enumerable.FirstOrDefault<ITypeMapper>((IEnumerable<ITypeMapper>)Settings.TypeMappers, (Func<ITypeMapper, bool>)((ITypeMapper m) => m.MappedType == genericType));
}
if (typeMapper != null) {
TaskAwaiter val = AwaitExtensions.GetAwaiter(typeMapper.GenerateSchemaAsync(schema, new TypeMapperContext(type, this, schemaResolver, parentAttributes)));
if (!val.get_IsCompleted()) {
await val;
TaskAwaiter val2 = default(TaskAwaiter);
val = val2;
}
val.GetResult();
return true;
}
if (type == typeof(JObject) || type == typeof(JToken) || type == typeof(object))
return true;
return false;
}
private async Task GenerateDictionaryAsync<TSchemaType>(Type type, TSchemaType schema, JsonSchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new
{
Type[] genericTypeArguments = type.GetGenericTypeArguments();
Type valueType = (genericTypeArguments.Length == 2) ? genericTypeArguments[1] : typeof(object);
if (valueType == typeof(object))
schema.AdditionalPropertiesSchema = JsonSchema4.CreateAnySchema();
else {
ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(valueType, schemaResolver), false).GetAwaiter();
if (!val.get_IsCompleted()) {
await val;
ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter);
val = val2;
}
JsonSchema4 result = (JsonSchema4)val.GetResult();
if (RequiresSchemaReference(valueType, null))
schema.AdditionalPropertiesSchema = new JsonSchema4 {
SchemaReference = result
};
else
schema.AdditionalPropertiesSchema = result;
}
schema.AllowAdditionalProperties = true;
}
protected virtual async Task GenerateObjectAsync<TSchemaType>(Type type, JsonContract contract, TSchemaType schema, JsonSchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new
{
schemaResolver.AddSchema(type, false, schema);
schema.AllowAdditionalProperties = false;
ConfiguredTaskAwaitable val = AwaitExtensions.ConfigureAwait(GeneratePropertiesAndInheritanceAsync(type, contract, schema, schemaResolver), false);
ConfiguredTaskAwaiter val2 = val.GetAwaiter();
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
if (!val2.get_IsCompleted()) {
await val2;
val2 = val3;
val3 = default(ConfiguredTaskAwaiter);
}
val2.GetResult();
if (Settings.GenerateKnownTypes) {
val = AwaitExtensions.ConfigureAwait(GenerateKnownTypesAsync(type, schemaResolver), false);
val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
val2 = val3;
}
val2.GetResult();
}
if (Settings.GenerateXmlObjects)
schema.GenerateXmlObjectForType(type);
}
private async Task GeneratePropertiesAndInheritanceAsync(Type type, JsonContract contract, JsonSchema4 schema, JsonSchemaResolver schemaResolver)
{
List<MemberInfo> propertiesAndFields = ReflectionExtensions.GetTypeInfo(type).GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public).OfType<MemberInfo>()
.Concat(ReflectionExtensions.GetTypeInfo(type).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public).Where(delegate(PropertyInfo p) {
if (!(p.GetGetMethod()?.IsPublic ?? false))
return p.GetSetMethod()?.IsPublic ?? false;
return true;
}))
.ToList();
JsonObjectContract jsonObjectContract = contract as JsonObjectContract;
ConfiguredTaskAwaitable val;
ConfiguredTaskAwaiter val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
if (jsonObjectContract != null) {
foreach (Newtonsoft.Json.Serialization.JsonProperty item in from p in jsonObjectContract.Properties
where p.DeclaringType == type
select p) {
bool flag;
try {
flag = (item.ShouldSerialize?.Invoke(null) ?? true);
} catch {
flag = true;
}
if (flag) {
MemberInfo memberInfo = propertiesAndFields.FirstOrDefault((MemberInfo p) => p.Name == item.UnderlyingName);
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if (!Settings.GenerateAbstractProperties && !(propertyInfo == (PropertyInfo)null)) {
MethodInfo getMethod = propertyInfo.GetGetMethod();
if ((object)getMethod != null && getMethod.IsAbstract)
continue;
MethodInfo setMethod = propertyInfo.GetSetMethod();
if ((object)setMethod != null && setMethod.IsAbstract)
continue;
}
val = AwaitExtensions.ConfigureAwait(LoadPropertyOrFieldAsync(item, memberInfo, type, schema, schemaResolver), false);
val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
val2 = val3;
val3 = default(ConfiguredTaskAwaiter);
}
val2.GetResult();
}
}
} else {
string[] allowedProperties = GetTypeProperties(type);
foreach (MemberInfo item2 in propertiesAndFields.Where(delegate(MemberInfo m) {
if (allowedProperties != null)
return allowedProperties.Contains(m.Name);
return true;
})) {
JsonPropertyAttribute jsonPropertyAttribute = item2.GetCustomAttributes(true).OfType<JsonPropertyAttribute>().SingleOrDefault();
Type propertyType = (item2 as PropertyInfo)?.PropertyType ?? ((FieldInfo)item2).FieldType;
Newtonsoft.Json.Serialization.JsonProperty obj2 = new Newtonsoft.Json.Serialization.JsonProperty {
AttributeProvider = new ReflectionAttributeProvider(item2),
PropertyType = propertyType,
Ignored = IsPropertyIgnored(propertyType, type, item2.GetCustomAttributes(true).OfType<Attribute>().ToArray())
};
if (jsonPropertyAttribute != null) {
obj2.PropertyName = (jsonPropertyAttribute.PropertyName ?? item2.Name);
obj2.Required = jsonPropertyAttribute.Required;
obj2.DefaultValueHandling = jsonPropertyAttribute.DefaultValueHandling;
obj2.TypeNameHandling = jsonPropertyAttribute.TypeNameHandling;
obj2.NullValueHandling = jsonPropertyAttribute.NullValueHandling;
obj2.TypeNameHandling = jsonPropertyAttribute.TypeNameHandling;
} else
obj2.PropertyName = item2.Name;
val = AwaitExtensions.ConfigureAwait(LoadPropertyOrFieldAsync(obj2, item2, type, schema, schemaResolver), false);
val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
val2 = val3;
val3 = default(ConfiguredTaskAwaiter);
}
val2.GetResult();
}
}
val = AwaitExtensions.ConfigureAwait(GenerateInheritanceAsync(type, schema, schemaResolver), false);
val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
val2 = val3;
}
val2.GetResult();
}
protected virtual string[] GetTypeProperties(Type type)
{
if (type == typeof(Exception))
return new string[4] {
"InnerException",
"Message",
"Source",
"StackTrace"
};
return null;
}
private unsafe async Task GenerateKnownTypesAsync(Type objectType, JsonSchemaResolver schemaResolver)
{
Type type = objectType;
do {
IEnumerable<Attribute> enumerable = (from a in ReflectionExtensions.GetTypeInfo(type).GetCustomAttributes(false)
where a.GetType().Name == "KnownTypeAttribute"
select a).OfType<Attribute>();
foreach (dynamic item in enumerable) {
if (item.Type != null) {
dynamic val = this.AddKnownTypeAsync(item.Type, schemaResolver).GetAwaiter();
if (!((byte)val.IsCompleted != 0)) {
ICriticalNotifyCompletion awaiter = val as ICriticalNotifyCompletion;
AsyncTaskMethodBuilder asyncTaskMethodBuilder;
if (awaiter == null) {
INotifyCompletion awaiter2 = (INotifyCompletion)val;
asyncTaskMethodBuilder.AwaitOnCompleted(ref awaiter2, ref *(<GenerateKnownTypesAsync>d__19*));
awaiter2 = null;
} else
asyncTaskMethodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref *(<GenerateKnownTypesAsync>d__19*));
awaiter = null;
;
}
val.GetResult();
} else {
if (!((item.MethodName != null) ? true : false))
throw new ArgumentException($"""{type.FullName}""", "type");
MethodInfo runtimeMethod = ReflectionExtensions.GetRuntimeMethod(type, (string)item.MethodName, new Type[0]);
if (runtimeMethod != (MethodInfo)null) {
Type[] array = runtimeMethod.Invoke(null, null) as Type[];
if (array != null) {
Type[] array2 = array;
foreach (Type type2 in array2) {
TaskAwaiter val2 = AwaitExtensions.GetAwaiter(AddKnownTypeAsync(type2, schemaResolver));
if (!val2.get_IsCompleted()) {
await val2;
TaskAwaiter val3 = default(TaskAwaiter);
val2 = val3;
val3 = default(TaskAwaiter);
}
val2.GetResult();
}
}
}
}
}
type = ReflectionExtensions.GetTypeInfo(type).BaseType;
} while (type != (Type)null);
}
private async Task AddKnownTypeAsync(Type type, JsonSchemaResolver schemaResolver)
{
bool isIntegerEnumeration = JsonObjectTypeDescription.FromType(type, ResolveContract(type), null, Settings.DefaultEnumHandling).Type == JsonObjectType.Integer;
if (!schemaResolver.HasSchema(type, isIntegerEnumeration)) {
ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(type, schemaResolver), false).GetAwaiter();
if (!val.get_IsCompleted()) {
await val;
ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter);
val = val2;
}
val.GetResult();
}
}
private async Task GenerateInheritanceAsync(Type type, JsonSchema4 schema, JsonSchemaResolver schemaResolver)
{
GenerateInheritanceDiscriminator(type, schema);
Type baseType = ReflectionExtensions.GetTypeInfo(type).BaseType;
if (baseType != (Type)null && baseType != typeof(object)) {
if (Settings.FlattenInheritanceHierarchy) {
ConfiguredTaskAwaitable val = AwaitExtensions.ConfigureAwait(GeneratePropertiesAndInheritanceAsync(baseType, (JsonObjectContract)ResolveContract(baseType), schema, schemaResolver), false);
ConfiguredTaskAwaiter val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
val2 = val3;
}
val2.GetResult();
} else {
ConfiguredTaskAwaiter val4 = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(baseType, schemaResolver), false).GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
ConfiguredTaskAwaiter val5 = default(ConfiguredTaskAwaiter);
val4 = val5;
}
!0 result = val4.GetResult();
if (RequiresSchemaReference(baseType, null)) {
if (schemaResolver.RootObject != ((JsonSchema4)result).ActualSchema)
schemaResolver.AppendSchema(((JsonSchema4)result).ActualSchema, Settings.SchemaNameGenerator.Generate(baseType));
schema.AllOf.Add(new JsonSchema4 {
SchemaReference = ((JsonSchema4)result).ActualSchema
});
} else
schema.AllOf.Add((JsonSchema4)result);
}
}
}
private void GenerateInheritanceDiscriminator(Type type, JsonSchema4 schema)
{
if (!Settings.FlattenInheritanceHierarchy) {
string text = TryGetInheritanceDiscriminator(ReflectionExtensions.GetTypeInfo(type).GetCustomAttributes(false).OfType<Attribute>());
if (!string.IsNullOrEmpty(text)) {
if (schema.Properties.ContainsKey(text))
throw new InvalidOperationException("The JSON property '" + text + "' is defined multiple times on type '" + type.FullName + "'.");
schema.Discriminator = text;
schema.Properties[text] = new JsonProperty {
Type = JsonObjectType.String,
IsRequired = true
};
}
}
}
private string TryGetInheritanceDiscriminator(IEnumerable<Attribute> typeAttributes)
{
dynamic val = (typeAttributes != null) ? typeAttributes.FirstOrDefault((Attribute a) => a.GetType().Name == "JsonConverterAttribute") : null;
if ((val != null) && ((Type)val.ConverterType).Name == "JsonInheritanceConverter") {
dynamic val2 = val.ConverterParameters != null;
if ((val2 ? false : true) ? val2 : (val2 & (val.ConverterParameters.Length > 0)))
return (string)val.ConverterParameters[0];
return JsonInheritanceConverter.DefaultDiscriminatorName;
}
return null;
}
private void LoadEnumerations(Type type, JsonSchema4 schema, JsonObjectTypeDescription typeDescription)
{
schema.Type = typeDescription.Type;
schema.Enumeration.Clear();
schema.EnumerationNames.Clear();
string[] names = Enum.GetNames(type);
foreach (string text in names) {
if (typeDescription.Type == JsonObjectType.Integer) {
object item = Convert.ChangeType(Enum.Parse(type, text), Enum.GetUnderlyingType(type));
schema.Enumeration.Add(item);
} else {
dynamic val = ReflectionExtensions.GetCustomAttributes(ReflectionExtensions.GetTypeInfo(type).GetDeclaredField(text), true).TryGetIfAssignableTo("System.Runtime.Serialization.EnumMemberAttribute", TypeNameStyle.FullName);
dynamic val2 = val != null;
if ((val2 ? false : true) ? val2 : (val2 & !string.IsNullOrEmpty(val.Value)))
schema.Enumeration.Add((string)val.Value);
else
schema.Enumeration.Add(text);
}
schema.EnumerationNames.Add(text);
}
}
private async Task LoadPropertyOrFieldAsync(Newtonsoft.Json.Serialization.JsonProperty property, MemberInfo propertyInfo, Type parentType, JsonSchema4 parentSchema, JsonSchemaResolver schemaResolver)
{
Type propertyType = property.PropertyType;
Attribute[] propertyAttributes = property.AttributeProvider.GetAttributes(true).ToArray();
JsonObjectTypeDescription propertyTypeDescription = JsonObjectTypeDescription.FromType(propertyType, ResolveContract(propertyType), null, Settings.DefaultEnumHandling);
if (!property.Ignored && !IsPropertyIgnoredBySettings(propertyType, parentType, propertyAttributes)) {
if (propertyType.Name == "Nullable`1")
propertyType = propertyType.GetGenericArguments()[0];
bool requiresSchemaReference = RequiresSchemaReference(propertyType, propertyAttributes);
JsonProperty jsonProperty;
if (requiresSchemaReference) {
ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<JsonSchema4>(GenerateAsync(propertyType, propertyAttributes, schemaResolver), false).GetAwaiter();
if (!val.get_IsCompleted()) {
await val;
ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter);
val = val2;
}
JsonSchema4 result = (JsonSchema4)val.GetResult();
jsonProperty = ((Settings.NullHandling != 0) ? new JsonProperty {
SchemaReference = result.ActualSchema
} : new JsonProperty {
OneOf = {
new JsonSchema4 {
SchemaReference = result.ActualSchema
}
}
});
} else {
ConfiguredTaskAwaiter val3 = AwaitExtensions.ConfigureAwait<JsonProperty>(GenerateAsync<JsonProperty>(propertyType, propertyAttributes, schemaResolver), false).GetAwaiter();
if (!val3.get_IsCompleted()) {
await val3;
ConfiguredTaskAwaiter val4 = default(ConfiguredTaskAwaiter);
val3 = val4;
}
jsonProperty = (JsonProperty)val3.GetResult();
}
DefaultContractResolver defaultContractResolver = Settings.ActualContractResolver as DefaultContractResolver;
string text = (defaultContractResolver != null) ? defaultContractResolver.GetResolvedPropertyName(property.PropertyName) : property.PropertyName;
if (parentSchema.Properties.ContainsKey(text))
throw new InvalidOperationException("The JSON property '" + text + "' is defined multiple times on type '" + parentType.FullName + "'.");
if (Settings.GenerateXmlObjects)
jsonProperty.GenerateXmlObjectForProperty(parentType, text, propertyAttributes);
parentSchema.Properties.Add(text, jsonProperty);
Attribute attribute = propertyAttributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.RequiredAttribute", TypeNameStyle.FullName);
bool flag = property.Required == Required.Always || property.Required == Required.AllowNull;
dynamic val5 = GetDataMemberAttribute(parentType, propertyAttributes)?.IsRequired == true;
bool flag2 = attribute != null;
dynamic val6 = flag2 ? ((object)flag2) : (flag2 | val5);
if ((val6) || ((val6 | flag) ? true : false))
parentSchema.RequiredProperties.Add(text);
bool flag3 = propertyTypeDescription.IsNullable && !flag2;
dynamic val7 = (!flag3) ? ((object)flag3) : (flag3 & (val5 == false));
dynamic val8 = (val7 ? false : true) ? val7 : (val7 & (property.Required == Required.Default || property.Required == Required.AllowNull));
if (val8) {
if (Settings.NullHandling == NullHandling.JsonSchema) {
if (requiresSchemaReference)
jsonProperty.OneOf.Add(new JsonSchema4 {
Type = JsonObjectType.Null
});
else if (jsonProperty.Type == JsonObjectType.None) {
jsonProperty.OneOf.Add(new JsonSchema4 {
Type = JsonObjectType.None
});
jsonProperty.OneOf.Add(new JsonSchema4 {
Type = JsonObjectType.Null
});
} else {
jsonProperty.Type |= JsonObjectType.Null;
}
}
} else if (Settings.NullHandling == NullHandling.Swagger && !parentSchema.RequiredProperties.Contains(text)) {
parentSchema.RequiredProperties.Add(text);
}
dynamic val9 = propertyAttributes.TryGetIfAssignableTo("System.ComponentModel.ReadOnlyAttribute", TypeNameStyle.FullName);
if (val9 != null)
jsonProperty.IsReadOnly = ((byte)val9.IsReadOnly != 0);
JsonProperty jsonProperty2 = jsonProperty;
ConfiguredTaskAwaiter val10 = AwaitExtensions.ConfigureAwait<string>(propertyInfo.GetDescriptionAsync(propertyAttributes), false).GetAwaiter();
if (!val10.get_IsCompleted()) {
await val10;
ConfiguredTaskAwaiter val11 = default(ConfiguredTaskAwaiter);
val10 = val11;
}
jsonProperty2.Description = (string)val10.GetResult();
ApplyPropertyAnnotations(jsonProperty, property, parentType, propertyAttributes, propertyTypeDescription);
}
}
private bool RequiresSchemaReference(Type type, IEnumerable<Attribute> parentAttributes)
{
JsonObjectTypeDescription jsonObjectTypeDescription = JsonObjectTypeDescription.FromType(type, ResolveContract(type), parentAttributes, Settings.DefaultEnumHandling);
ITypeMapper typeMapper = Settings.TypeMappers.FirstOrDefault((ITypeMapper m) => m.MappedType == type);
if (typeMapper != null)
return typeMapper.UseReference;
if (!jsonObjectTypeDescription.IsDictionary) {
if (!jsonObjectTypeDescription.Type.HasFlag(JsonObjectType.Object))
return jsonObjectTypeDescription.IsEnum;
return true;
}
return false;
}
private JsonContract ResolveContract(Type type)
{
if (ReflectionExtensions.GetTypeInfo(type).IsGenericTypeDefinition)
return null;
return Settings.ActualContractResolver.ResolveContract(type);
}
private bool IsPropertyIgnored(Type propertyType, Type parentType, Attribute[] propertyAttributes)
{
if (propertyAttributes.Any((Attribute a) => a is JsonIgnoreAttribute))
return true;
bool flag = HasDataContractAttribute(parentType);
dynamic val = (!flag) ? ((object)flag) : (flag & (GetDataMemberAttribute(parentType, propertyAttributes) == null));
if ((val ? false : true) ? val : (val & !propertyAttributes.Any((Attribute a) => a is JsonPropertyAttribute)))
return true;
return IsPropertyIgnoredBySettings(propertyType, parentType, propertyAttributes);
}
private bool IsPropertyIgnoredBySettings(Type propertyType, Type parentType, Attribute[] propertyAttributes)
{
if (Settings.IgnoreObsoleteProperties && propertyAttributes.Any((Attribute a) => a is ObsoleteAttribute))
return true;
return false;
}
private static dynamic GetDataMemberAttribute(Type parentType, Attribute[] propertyAttributes)
{
if (!HasDataContractAttribute(parentType))
return null;
return propertyAttributes.FirstOrDefault((Attribute a) => a.GetType().Name == "DataMemberAttribute");
}
private static bool HasDataContractAttribute(Type parentType)
{
return ReflectionExtensions.GetCustomAttributes(ReflectionExtensions.GetTypeInfo(parentType), true).Any((Attribute a) => a.GetType().Name == "DataContractAttribute");
}
public void ApplyPropertyAnnotations(JsonSchema4 jsonProperty, Newtonsoft.Json.Serialization.JsonProperty property, Type parentType, IEnumerable<Attribute> attributes, JsonObjectTypeDescription propertyTypeDescription)
{
dynamic val = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.DisplayAttribute", TypeNameStyle.FullName);
dynamic val2 = val != null;
if ((val2 ? false : true) ? val2 : (val2 & (val.Name != null)))
jsonProperty.Title = (string)val.Name;
if (property != null)
jsonProperty.Default = ConvertDefaultValue(property);
else {
dynamic val3 = attributes.TryGetIfAssignableTo("System.ComponentModel.DefaultValueAttribute", TypeNameStyle.FullName);
if (val3 != null)
jsonProperty.Default = (object)val3.Value;
}
dynamic val4 = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.RegularExpressionAttribute", TypeNameStyle.FullName);
if (val4 != null) {
if (propertyTypeDescription.IsDictionary)
jsonProperty.AdditionalPropertiesSchema.Pattern = (string)val4.Pattern;
else
jsonProperty.Pattern = (string)val4.Pattern;
}
if (propertyTypeDescription.Type == JsonObjectType.Number || propertyTypeDescription.Type == JsonObjectType.Integer) {
dynamic val5 = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.RangeAttribute", TypeNameStyle.FullName);
if (val5 != null) {
val2 = (val5.Minimum != null);
if ((val2 ? false : true) ? val2 : (val2 & (val5.Minimum > -1.7976931348623157E+308)))
jsonProperty.Minimum = (decimal)(double)val5.Minimum;
val2 = (val5.Maximum != null);
if ((val2 ? false : true) ? val2 : (val2 & (val5.Maximum < 1.7976931348623157E+308)))
jsonProperty.Maximum = (decimal)(double)val5.Maximum;
}
MultipleOfAttribute multipleOfAttribute = attributes.OfType<MultipleOfAttribute>().SingleOrDefault();
if (multipleOfAttribute != null)
jsonProperty.MultipleOf = multipleOfAttribute.MultipleOf;
}
dynamic val6 = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.MinLengthAttribute", TypeNameStyle.FullName);
val2 = (val6 != null);
if ((val2 ? false : true) ? val2 : (val2 & (val6.Length != null))) {
if (propertyTypeDescription.Type == JsonObjectType.String)
jsonProperty.MinLength = (int?)val6.Length;
else if (propertyTypeDescription.Type == JsonObjectType.Array) {
jsonProperty.MinItems = (int)val6.Length;
}
}
dynamic val7 = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.MaxLengthAttribute", TypeNameStyle.FullName);
val2 = (val7 != null);
if ((val2 ? false : true) ? val2 : (val2 & (val7.Length != null))) {
if (propertyTypeDescription.Type == JsonObjectType.String)
jsonProperty.MaxLength = (int?)val7.Length;
else if (propertyTypeDescription.Type == JsonObjectType.Array) {
jsonProperty.MaxItems = (int)val7.Length;
}
}
dynamic val8 = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.StringLengthAttribute", TypeNameStyle.FullName);
if ((val8 != null) && propertyTypeDescription.Type == JsonObjectType.String) {
jsonProperty.MinLength = (int?)val8.MinimumLength;
jsonProperty.MaxLength = (int?)val8.MaximumLength;
}
dynamic val9 = attributes.TryGetIfAssignableTo("System.ComponentModel.DataAnnotations.DataTypeAttribute", TypeNameStyle.FullName);
if (val9 != null) {
dynamic val10 = val9.DataType.ToString();
if (DataTypeFormats.ContainsKey(val10))
jsonProperty.Format = (string)DataTypeFormats[val10];
}
}
private object ConvertDefaultValue(Newtonsoft.Json.Serialization.JsonProperty property)
{
if (property.DefaultValue != null && ReflectionExtensions.GetTypeInfo(property.DefaultValue.GetType()).IsEnum) {
Type typeInfo = ReflectionExtensions.GetTypeInfo(typeof(StringEnumConverter));
JsonConverter converter = property.Converter;
if (typeInfo.IsAssignableFrom((converter != null) ? ReflectionExtensions.GetTypeInfo(converter.GetType()) : null))
return property.DefaultValue.ToString();
return (int)property.DefaultValue;
}
return property.DefaultValue;
}
}
}