From cce0e36e5b7bd31dc95103f0998b6a5ae1ca4532 Mon Sep 17 00:00:00 2001 From: Rico Suter Date: Tue, 31 Oct 2023 16:43:11 +0100 Subject: [PATCH] Update Namotion.Reflection --- src/Directory.Packages.props | 2 +- .../NewtonsoftJsonReflectionService.cs | 8 +- .../Generation/DefaultSchemaNameGenerator.cs | 11 +-- .../Generation/JsonSchemaGenerator.cs | 81 +++++++++---------- .../Generation/ReflectionServiceBase.cs | 21 ++--- .../SystemTextJsonReflectionService.cs | 14 ++-- .../Infrastructure/TypeExtensions.cs | 14 ++-- .../Infrastructure/XmlObjectExtension.cs | 14 ++-- src/NJsonSchema/JsonReferenceResolver.cs | 2 +- .../Visitors/AsyncJsonReferenceVisitorBase.cs | 4 +- .../Visitors/JsonReferenceVisitorBase.cs | 5 +- 11 files changed, 93 insertions(+), 83 deletions(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 8d4349087..9bb9bf996 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -10,7 +10,7 @@ - + diff --git a/src/NJsonSchema.NewtonsoftJson/Generation/NewtonsoftJsonReflectionService.cs b/src/NJsonSchema.NewtonsoftJson/Generation/NewtonsoftJsonReflectionService.cs index fb18337bb..56bb7d58c 100644 --- a/src/NJsonSchema.NewtonsoftJson/Generation/NewtonsoftJsonReflectionService.cs +++ b/src/NJsonSchema.NewtonsoftJson/Generation/NewtonsoftJsonReflectionService.cs @@ -39,7 +39,7 @@ public class NewtonsoftJsonReflectionService : ReflectionServiceBase public override bool IsNullable(ContextualType contextualType, ReferenceTypeNullHandling defaultReferenceTypeNullHandling) { - var jsonPropertyAttribute = contextualType.GetContextAttribute(); + var jsonPropertyAttribute = contextualType.GetContextAttribute(true); if (jsonPropertyAttribute != null && jsonPropertyAttribute.Required == Required.DisallowNull) { return false; @@ -117,7 +117,7 @@ public override void GenerateProperties(JsonSchema schema, ContextualType contex // TODO: Remove this hacky code (used to support serialization of exceptions and restore the old behavior [pre 9.x]) foreach (var accessorInfo in contextualAccessors.Where(m => allowedProperties == null || allowedProperties.Contains(m.Name))) { - var attribute = accessorInfo.GetContextAttribute(); + var attribute = accessorInfo.GetAttribute(true); var memberType = (accessorInfo as ContextualPropertyInfo)?.PropertyInfo.PropertyType ?? (accessorInfo as ContextualFieldInfo)?.FieldInfo.FieldType; @@ -173,7 +173,9 @@ private void LoadPropertyOrField(JsonProperty jsonProperty, ContextualAccessorIn } } - var requiredAttribute = accessorInfo.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.RequiredAttribute"); + var requiredAttribute = accessorInfo + .GetAttributes(true) + .FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.RequiredAttribute"); var hasJsonNetAttributeRequired = jsonProperty.Required == Required.Always || jsonProperty.Required == Required.AllowNull; var isDataContractMemberRequired = schemaGenerator.GetDataMemberAttribute(accessorInfo, parentType)?.IsRequired == true; diff --git a/src/NJsonSchema/Generation/DefaultSchemaNameGenerator.cs b/src/NJsonSchema/Generation/DefaultSchemaNameGenerator.cs index db04ce3ea..5d934ae6d 100644 --- a/src/NJsonSchema/Generation/DefaultSchemaNameGenerator.cs +++ b/src/NJsonSchema/Generation/DefaultSchemaNameGenerator.cs @@ -23,7 +23,8 @@ public virtual string Generate(Type type) { var cachedType = type.ToCachedType(); - var jsonSchemaAttribute = cachedType.GetInheritedAttribute(); + var jsonSchemaAttribute = cachedType.GetAttribute(true); + if (!string.IsNullOrEmpty(jsonSchemaAttribute?.Name)) { return jsonSchemaAttribute!.Name!; @@ -44,10 +45,10 @@ public virtual string Generate(Type type) private static string GetName(CachedType cType) { return - cType.TypeName == "Int16" ? GetNullableDisplayName(cType, "Short") : - cType.TypeName == "Int32" ? GetNullableDisplayName(cType, "Integer") : - cType.TypeName == "Int64" ? GetNullableDisplayName(cType, "Long") : - GetNullableDisplayName(cType, cType.TypeName); + cType.Name == "Int16" ? GetNullableDisplayName(cType, "Short") : + cType.Name == "Int32" ? GetNullableDisplayName(cType, "Integer") : + cType.Name == "Int64" ? GetNullableDisplayName(cType, "Long") : + GetNullableDisplayName(cType, cType.Name); } private static string GetNullableDisplayName(CachedType type, string actual) diff --git a/src/NJsonSchema/Generation/JsonSchemaGenerator.cs b/src/NJsonSchema/Generation/JsonSchemaGenerator.cs index ed7f7c224..4dac96e46 100644 --- a/src/NJsonSchema/Generation/JsonSchemaGenerator.cs +++ b/src/NJsonSchema/Generation/JsonSchemaGenerator.cs @@ -338,7 +338,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription { var contextualType = typeDescription.ContextualType; - dynamic? displayAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.DisplayAttribute"); + dynamic? displayAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.DisplayAttribute"); if (displayAttribute != null) { // GetName returns null if the Name property on the attribute is not specified. @@ -349,7 +349,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription } } - dynamic? defaultValueAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DefaultValueAttribute"); + dynamic? defaultValueAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DefaultValueAttribute"); if (defaultValueAttribute != null) { if (typeDescription.IsEnum && @@ -363,7 +363,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription } } - dynamic? regexAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.RegularExpressionAttribute"); + dynamic? regexAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.RegularExpressionAttribute"); if (regexAttribute != null) { if (typeDescription.IsDictionary) @@ -384,16 +384,16 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription if (typeDescription.Type == JsonObjectType.Number || typeDescription.Type == JsonObjectType.Integer) { - ApplyRangeAttribute(schema, contextualType.ContextAttributes); + ApplyRangeAttribute(schema, contextualType.GetContextAttributes(true)); - var multipleOfAttribute = contextualType.ContextAttributes.OfType().SingleOrDefault(); + var multipleOfAttribute = contextualType.GetContextAttribute(true); if (multipleOfAttribute != null) { schema.MultipleOf = multipleOfAttribute.MultipleOf; } } - dynamic? minLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.MinLengthAttribute"); + dynamic? minLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.MinLengthAttribute"); if (minLengthAttribute?.Length != null) { if (typeDescription.Type == JsonObjectType.String) @@ -406,7 +406,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription } } - dynamic? maxLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.MaxLengthAttribute"); + dynamic? maxLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.MaxLengthAttribute"); if (maxLengthAttribute?.Length != null) { if (typeDescription.Type == JsonObjectType.String) @@ -419,7 +419,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription } } - dynamic? stringLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.StringLengthAttribute"); + dynamic? stringLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.StringLengthAttribute"); if (stringLengthAttribute != null) { if (typeDescription.Type == JsonObjectType.String) @@ -429,7 +429,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription } } - dynamic? dataTypeAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.DataTypeAttribute"); + dynamic? dataTypeAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.DataTypeAttribute"); if (dataTypeAttribute != null) { var dataType = dataTypeAttribute.DataType.ToString(); @@ -484,7 +484,7 @@ public virtual void ApplyDataAnnotations(JsonSchema schema, JsonTypeDescription return null; } - /// Generates the example from the accesor's xml docs. + /// Generates the example from the accessor's xml docs. /// The accessor info. /// The JToken or null. public virtual object? GenerateExample(ContextualAccessorInfo accessorInfo) @@ -595,14 +595,14 @@ protected virtual void GenerateObject(JsonSchema schema, JsonTypeDescription typ typeDescription.ApplyType(schema); - var jsonSchemaAttribute = contextualType.GetInheritedAttribute(); + var jsonSchemaAttribute = contextualType.GetContextOrTypeAttribute(true); var itemType = jsonSchemaAttribute?.ArrayItem?.ToContextualType() ?? contextualType.EnumerableItemType ?? contextualType.GenericArguments.FirstOrDefault(); if (itemType != null) { - var itemIsNullable = contextualType.GetContextAttribute() != null || + var itemIsNullable = contextualType.IsContextAttributeDefined(true) || itemType.Nullability == Nullability.Nullable; schema.Item = GenerateWithReferenceAndNullability( @@ -624,13 +624,13 @@ protected virtual void GenerateObject(JsonSchema schema, JsonTypeDescription typ schema.Item = JsonSchema.CreateAnySchema(); } - dynamic? minLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("MinLengthAttribute", TypeNameStyle.Name); + dynamic? minLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("MinLengthAttribute", TypeNameStyle.Name); if (minLengthAttribute != null && ObjectExtensions.HasProperty(minLengthAttribute, "Length")) { schema.MinItems = minLengthAttribute?.Length; } - dynamic? maxLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("MaxLengthAttribute", TypeNameStyle.Name); + dynamic? maxLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("MaxLengthAttribute", TypeNameStyle.Name); if (maxLengthAttribute != null && ObjectExtensions.HasProperty(maxLengthAttribute, "Length")) { schema.MaxItems = maxLengthAttribute?.Length; @@ -659,7 +659,7 @@ protected virtual void GenerateDictionary(TSchemaType schema, JsonT var valueType = genericTypeArguments.Length == 2 ? genericTypeArguments[1] : typeof(object).ToContextualType(); - var patternPropertiesAttributes = contextualType.ContextAttributes.OfType(); + var patternPropertiesAttributes = contextualType.GetContextAttributes(true).OfType(); if (patternPropertiesAttributes.Any()) { schema.AllowAdditionalProperties = false; @@ -676,13 +676,13 @@ protected virtual void GenerateDictionary(TSchemaType schema, JsonT schema.AllowAdditionalProperties = true; } - dynamic? minLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("MinLengthAttribute", TypeNameStyle.Name); + dynamic? minLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("MinLengthAttribute", TypeNameStyle.Name); if (minLengthAttribute != null && ObjectExtensions.HasProperty(minLengthAttribute, "Length")) { schema.MinProperties = minLengthAttribute?.Length; } - dynamic? maxLengthAttribute = contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("MaxLengthAttribute", TypeNameStyle.Name); + dynamic? maxLengthAttribute = contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("MaxLengthAttribute", TypeNameStyle.Name); if (maxLengthAttribute != null && ObjectExtensions.HasProperty(maxLengthAttribute, "Length")) { schema.MaxProperties = maxLengthAttribute?.Length; @@ -699,7 +699,7 @@ protected virtual void GenerateEnum(JsonSchema schema, JsonTypeDescription typeD schema.Type = typeDescription.Type; schema.Enumeration.Clear(); schema.EnumerationNames.Clear(); - schema.IsFlagEnumerable = contextualType.GetInheritedAttribute() != null; + schema.IsFlagEnumerable = contextualType.IsAttributeDefined(true); Func? enumValueConverter = null; var underlyingType = Enum.GetUnderlyingType(contextualType.Type); @@ -753,7 +753,7 @@ private TSchema GenerateDictionaryValueSchema(JsonSchemaResolver schema else { var valueTypeInfo = Settings.ReflectionService.GetDescription(valueType, Settings.DefaultDictionaryValueReferenceTypeNullHandling, Settings); - var valueTypeIsNullable = valueType.GetContextAttribute() != null || + var valueTypeIsNullable = valueType.IsContextAttributeDefined(true) || valueTypeInfo.IsNullable; return GenerateWithReferenceAndNullability(valueType, valueTypeIsNullable, schemaResolver); @@ -764,7 +764,7 @@ private void ApplyAdditionalProperties(TSchemaType schema, Type typ where TSchemaType : JsonSchema, new() { var extensionDataProperty = type.GetContextualProperties() - .FirstOrDefault(p => p.ContextAttributes.Any(a => + .FirstOrDefault(p => p.GetAttributes(true).Any(a => Namotion.Reflection.TypeExtensions.IsAssignableToTypeName(a.GetType(), "JsonExtensionDataAttribute", TypeNameStyle.Name))); if (extensionDataProperty != null) @@ -790,7 +790,7 @@ private void ApplySchemaProcessors(JsonSchema schema, ContextualType contextualT } var operationProcessorAttributes = contextualType - .InheritedAttributes + .GetAttributes(true) .GetAssignableToTypeName(nameof(JsonSchemaProcessorAttribute), TypeNameStyle.Name); foreach (dynamic attribute in operationProcessorAttributes) @@ -812,7 +812,7 @@ private bool TryHandleSpecialTypes(TSchemaType schema, ContextualTy if (typeMapper != null) { - var context = new TypeMapperContext(contextualType.OriginalType, this, schemaResolver, contextualType.ContextAttributes); + var context = new TypeMapperContext(contextualType.OriginalType, this, schemaResolver, contextualType.GetContextAttributes(true)); typeMapper.GenerateSchema(schema, context); return true; } @@ -862,7 +862,7 @@ private bool TryHandleSpecialTypes(TSchemaType schema, ContextualTy } /// - /// Chesk whether a member info is abstract. + /// Checks whether a member info is abstract. /// /// /// @@ -954,8 +954,8 @@ private void AddKnownType(Type type, JsonSchemaResolver schemaResolver) var baseType = type.BaseType; if (baseType != null && baseType.Type != typeof(object) && baseType.Type != typeof(ValueType)) { - if (baseType.Attributes.FirstAssignableToTypeNameOrDefault("JsonSchemaIgnoreAttribute", TypeNameStyle.Name) == null && - baseType.Attributes.FirstAssignableToTypeNameOrDefault("SwaggerIgnoreAttribute", TypeNameStyle.Name) == null && + if (baseType.GetContextOrTypeAttributes(false).FirstAssignableToTypeNameOrDefault("JsonSchemaIgnoreAttribute", TypeNameStyle.Name) == null && + baseType.GetContextOrTypeAttributes(false).FirstAssignableToTypeNameOrDefault("SwaggerIgnoreAttribute", TypeNameStyle.Name) == null && Settings.ExcludedTypeNames?.Contains(baseType.Type.FullName) != true) { if (Settings.GetActualFlattenInheritanceHierarchy(type)) @@ -1052,8 +1052,8 @@ private void GenerateInheritanceDiscriminator(Type type, JsonSchema schema, Json if (!existingProperty.ActualTypeSchema.Type.IsInteger() && !existingProperty.ActualTypeSchema.Type.IsString()) { - throw new InvalidOperationException("The JSON discriminator property '" + discriminatorName + - "' must be a string|int property on type '" + type.FullName + + throw new InvalidOperationException("The JSON discriminator property '" + discriminatorName + + "' must be a string|int property on type '" + type.FullName + "' (it is recommended to not implement the discriminator property at all)."); } @@ -1076,7 +1076,7 @@ private void GenerateInheritanceDiscriminator(Type type, JsonSchema schema, Json IsRequired = true }; } - } + } } else { @@ -1193,7 +1193,7 @@ public string GetDiscriminatorValue(Type type) } } - dynamic? readOnlyAttribute = property.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.ReadOnlyAttribute"); + dynamic? readOnlyAttribute = property.GetAttributes(true).FirstAssignableToTypeNameOrDefault("System.ComponentModel.ReadOnlyAttribute"); if (readOnlyAttribute != null) { propertySchema.IsReadOnly = readOnlyAttribute.IsReadOnly; @@ -1209,7 +1209,7 @@ public string GetDiscriminatorValue(Type type) propertySchema.Example = GenerateExample(property); } - dynamic? obsoleteAttribute = property.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ObsoleteAttribute"); + dynamic? obsoleteAttribute = property.GetAttributes(true).FirstAssignableToTypeNameOrDefault("System.ObsoleteAttribute"); if (obsoleteAttribute != null) { propertySchema.IsDeprecated = true; @@ -1234,12 +1234,12 @@ public string GetDiscriminatorValue(Type type) /// The result. public virtual bool IsPropertyIgnored(ContextualAccessorInfo accessorInfo, Type parentType) { - if (accessorInfo.GetContextAttribute() != null) + if (accessorInfo.IsAttributeDefined(true)) { return true; } - if (accessorInfo.GetContextAttribute() == null && + if (accessorInfo.IsAttributeDefined(true) == false && HasDataContractAttribute(parentType) && GetDataMemberAttribute(accessorInfo, parentType) == null) { @@ -1257,12 +1257,12 @@ public virtual bool IsPropertyIgnored(ContextualAccessorInfo accessorInfo, Type public bool IsPropertyIgnoredBySettings(ContextualAccessorInfo accessorInfo) { if (Settings.IgnoreObsoleteProperties && - accessorInfo.GetContextAttribute() != null) + accessorInfo.IsAttributeDefined(true)) { return true; } - if (accessorInfo.GetContextAttribute() != null) + if (accessorInfo.IsAttributeDefined(true)) { return true; } @@ -1283,12 +1283,13 @@ public bool IsPropertyIgnoredBySettings(ContextualAccessorInfo accessorInfo) return null; } - return accessorInfo.ContextAttributes.FirstAssignableToTypeNameOrDefault("DataMemberAttribute", TypeNameStyle.Name); + return accessorInfo.GetAttributes(true).FirstAssignableToTypeNameOrDefault("DataMemberAttribute", TypeNameStyle.Name); } private bool HasDataContractAttribute(Type parentType) { - return parentType.ToCachedType().InheritedAttributes + return parentType.ToCachedType() + .GetAttributes(true) .FirstAssignableToTypeNameOrDefault("DataContractAttribute", TypeNameStyle.Name) != null; } @@ -1341,10 +1342,8 @@ private void ApplyRangeAttribute(JsonSchema schema, IEnumerable paren private void ApplyTypeExtensionDataAttributes(JsonSchema schema, ContextualType contextualType) { - var extensionAttributes = contextualType.OriginalType - .GetTypeInfo() - .GetCustomAttributes() - .OfType() + var extensionAttributes = contextualType + .GetAttributes(true) .ToArray(); ApplyTypeExtensionDataAttributes(schema, extensionAttributes); @@ -1353,7 +1352,7 @@ private void ApplyTypeExtensionDataAttributes(JsonSchema schema, ContextualType private void ApplyPropertyExtensionDataAttributes(JsonSchemaProperty propertySchema, ContextualAccessorInfo accessorInfo) { var extensionAttributes = accessorInfo - .GetContextAttributes() + .GetAttributes(true) .ToArray(); ApplyTypeExtensionDataAttributes(propertySchema, extensionAttributes); diff --git a/src/NJsonSchema/Generation/ReflectionServiceBase.cs b/src/NJsonSchema/Generation/ReflectionServiceBase.cs index 7302b8a06..97798d619 100644 --- a/src/NJsonSchema/Generation/ReflectionServiceBase.cs +++ b/src/NJsonSchema/Generation/ReflectionServiceBase.cs @@ -38,7 +38,7 @@ public JsonTypeDescription GetDescription(ContextualType contextualType, Referen var type = contextualType.OriginalType; var isNullable = IsNullable(contextualType, defaultReferenceTypeNullHandling); - var jsonSchemaTypeAttribute = contextualType.GetAttribute(); + var jsonSchemaTypeAttribute = contextualType.GetContextOrTypeAttribute(true); if (jsonSchemaTypeAttribute != null) { type = jsonSchemaTypeAttribute.Type; @@ -50,7 +50,7 @@ public JsonTypeDescription GetDescription(ContextualType contextualType, Referen } } - var jsonSchemaAttribute = contextualType.GetAttribute(); + var jsonSchemaAttribute = contextualType.GetContextOrTypeAttribute(true); ; if (jsonSchemaAttribute != null) { var classType = jsonSchemaAttribute.Type != JsonObjectType.None ? jsonSchemaAttribute.Type : JsonObjectType.Object; @@ -235,12 +235,12 @@ protected virtual JsonTypeDescription GetDescription(ContextualType contextualTy /// true if the type can be null. public virtual bool IsNullable(ContextualType contextualType, ReferenceTypeNullHandling defaultReferenceTypeNullHandling) { - if (contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("NotNullAttribute", TypeNameStyle.Name) != null) + if (contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("NotNullAttribute", TypeNameStyle.Name) != null) { return false; } - if (contextualType.ContextAttributes.FirstAssignableToTypeNameOrDefault("CanBeNullAttribute", TypeNameStyle.Name) != null) + if (contextualType.GetContextAttributes(true).FirstAssignableToTypeNameOrDefault("CanBeNullAttribute", TypeNameStyle.Name) != null) { return true; } @@ -283,7 +283,7 @@ protected virtual bool IsBinary(ContextualType contextualType) { // TODO: Move all file handling to NSwag. How? - var parameterTypeName = contextualType.TypeName; + var parameterTypeName = contextualType.Name; return parameterTypeName == "IFormFile" || contextualType.IsAssignableToTypeName("HttpPostedFile", TypeNameStyle.Name) || contextualType.IsAssignableToTypeName("HttpPostedFileBase", TypeNameStyle.Name) || @@ -298,7 +298,7 @@ protected virtual bool IsBinary(ContextualType contextualType) /// true or false. private bool IsIAsyncEnumerableType(ContextualType contextualType) { - return contextualType.TypeName == "IAsyncEnumerable`1"; + return contextualType.Name == "IAsyncEnumerable`1"; } /// Checks whether the given type is an array type. @@ -311,7 +311,7 @@ protected virtual bool IsArrayType(ContextualType contextualType) return false; } - if (contextualType.TypeName == "ObservableCollection`1") + if (contextualType.Name == "ObservableCollection`1") { return true; } @@ -327,7 +327,7 @@ protected virtual bool IsArrayType(ContextualType contextualType) /// true or false. protected virtual bool IsDictionaryType(ContextualType contextualType) { - if (contextualType.TypeName == "IDictionary`2" || contextualType.TypeName == "IReadOnlyDictionary`2") + if (contextualType.Name == "IDictionary`2" || contextualType.Name == "IReadOnlyDictionary`2") { return true; } @@ -339,7 +339,10 @@ protected virtual bool IsDictionaryType(ContextualType contextualType) private bool HasStringEnumConverter(ContextualType contextualType) { - dynamic? jsonConverterAttribute = contextualType.Attributes?.FirstOrDefault(a => a.GetType().Name == "JsonConverterAttribute"); + dynamic? jsonConverterAttribute = contextualType + .GetContextOrTypeAttributes(true)? + .FirstOrDefault(a => a.GetType().Name == "JsonConverterAttribute"); + if (jsonConverterAttribute != null && ObjectExtensions.HasProperty(jsonConverterAttribute, "ConverterType")) { var converterType = jsonConverterAttribute?.ConverterType as Type; diff --git a/src/NJsonSchema/Generation/SystemTextJsonReflectionService.cs b/src/NJsonSchema/Generation/SystemTextJsonReflectionService.cs index c05573381..71cb2cea8 100644 --- a/src/NJsonSchema/Generation/SystemTextJsonReflectionService.cs +++ b/src/NJsonSchema/Generation/SystemTextJsonReflectionService.cs @@ -40,14 +40,14 @@ public override void GenerateProperties(JsonSchema schema, ContextualType contex } if (accessorInfo.Name == "EqualityContract" && - accessorInfo.ContextAttributes.OfType().Any()) + accessorInfo.IsAttributeDefined(true)) { continue; } var propertyIgnored = false; var jsonIgnoreAttribute = accessorInfo - .ContextAttributes + .GetAttributes(true) .FirstAssignableToTypeNameOrDefault("System.Text.Json.Serialization.JsonIgnoreAttribute", TypeNameStyle.FullName); if (jsonIgnoreAttribute != null) @@ -61,8 +61,8 @@ public override void GenerateProperties(JsonSchema schema, ContextualType contex var ignored = propertyIgnored || schemaGenerator.IsPropertyIgnoredBySettings(accessorInfo) - || accessorInfo.ContextAttributes - .FirstAssignableToTypeNameOrDefault("System.Text.Json.Serialization.JsonExtensionDataAttribute", TypeNameStyle.FullName) != null; + || accessorInfo.GetAttributes(true) + .FirstAssignableToTypeNameOrDefault("System.Text.Json.Serialization.JsonExtensionDataAttribute", TypeNameStyle.FullName) != null; if (!ignored) { @@ -82,7 +82,9 @@ public override void GenerateProperties(JsonSchema schema, ContextualType contex } } - var requiredAttribute = accessorInfo.ContextAttributes.FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.RequiredAttribute"); + var requiredAttribute = accessorInfo + .GetAttributes(true) + .FirstAssignableToTypeNameOrDefault("System.ComponentModel.DataAnnotations.RequiredAttribute"); var isDataContractMemberRequired = schemaGenerator.GetDataMemberAttribute(accessorInfo, contextualType.Type)?.IsRequired == true; @@ -132,7 +134,7 @@ public override string GetPropertyName(ContextualAccessorInfo accessorInfo, Json private static string GetPropertyName(ContextualAccessorInfo accessorInfo, SystemTextJsonSchemaGeneratorSettings settings) { - dynamic? jsonPropertyNameAttribute = accessorInfo.ContextAttributes + dynamic? jsonPropertyNameAttribute = accessorInfo.GetAttributes(true) .FirstAssignableToTypeNameOrDefault("System.Text.Json.Serialization.JsonPropertyNameAttribute", TypeNameStyle.FullName); if (!string.IsNullOrEmpty(jsonPropertyNameAttribute?.Name)) diff --git a/src/NJsonSchema/Infrastructure/TypeExtensions.cs b/src/NJsonSchema/Infrastructure/TypeExtensions.cs index d6e33c8f5..749a70baa 100644 --- a/src/NJsonSchema/Infrastructure/TypeExtensions.cs +++ b/src/NJsonSchema/Infrastructure/TypeExtensions.cs @@ -59,20 +59,20 @@ public static string GetName(this ContextualAccessorInfo accessorInfo) private static string GetNameWithoutCache(ContextualAccessorInfo accessorInfo) { - var jsonPropertyAttribute = accessorInfo.AccessorType.GetContextAttribute(); + var jsonPropertyAttribute = accessorInfo.GetAttribute(true); if (jsonPropertyAttribute != null && !string.IsNullOrEmpty(jsonPropertyAttribute.PropertyName)) { return jsonPropertyAttribute.PropertyName!; } - var dataMemberAttribute = accessorInfo.AccessorType.GetContextAttribute(); + var dataMemberAttribute = accessorInfo.GetAttribute(true); if (dataMemberAttribute != null && !string.IsNullOrEmpty(dataMemberAttribute.Name)) { var dataContractAttribute = accessorInfo .MemberInfo .DeclaringType? .ToCachedType() - .GetInheritedAttribute(); + .GetAttribute(true); if (dataContractAttribute != null) { @@ -89,7 +89,9 @@ private static string GetNameWithoutCache(ContextualAccessorInfo accessorInfo) /// The description or null if no description is available. public static string? GetDescription(this CachedType type, IXmlDocsSettings xmlDocsSettings) { - var attributes = type is ContextualType contextualType ? contextualType.ContextAttributes : type.InheritedAttributes; + var attributes = type is ContextualType contextualType ? + contextualType.GetContextOrTypeAttributes(true) : + type.GetAttributes(true); var description = GetDescription(attributes); if (description != null) @@ -115,7 +117,7 @@ private static string GetNameWithoutCache(ContextualAccessorInfo accessorInfo) /// The description or null if no description is available. public static string? GetDescription(this ContextualAccessorInfo accessorInfo, IXmlDocsSettings xmlDocsSettings) { - var description = GetDescription(accessorInfo.AccessorType.Attributes); + var description = GetDescription(accessorInfo.GetAttributes(true)); if (description != null) { return description; @@ -139,7 +141,7 @@ private static string GetNameWithoutCache(ContextualAccessorInfo accessorInfo) /// The description or null if no description is available. public static string? GetDescription(this ContextualParameterInfo parameter, IXmlDocsSettings xmlDocsSettings) { - var description = GetDescription(parameter.ContextAttributes); + var description = GetDescription(parameter.GetAttributes(true)); if (description != null) { return description; diff --git a/src/NJsonSchema/Infrastructure/XmlObjectExtension.cs b/src/NJsonSchema/Infrastructure/XmlObjectExtension.cs index ff2ae3f6c..2ebd63a1d 100644 --- a/src/NJsonSchema/Infrastructure/XmlObjectExtension.cs +++ b/src/NJsonSchema/Infrastructure/XmlObjectExtension.cs @@ -22,7 +22,7 @@ public static class XmlObjectExtension /// The type of the JSON Schema. public static void GenerateXmlObjectForType(this JsonSchema schema, Type type) { - var attributes = type.ToCachedType().InheritedAttributes; + var attributes = type.ToCachedType().GetAttributes(true); if (attributes.Any()) { dynamic? xmlTypeAttribute = attributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlTypeAttribute"); @@ -49,7 +49,7 @@ public static void GenerateXmlObjectForArrayType(this JsonSchema schema) public static void GenerateXmlObjectForItemType(this JsonSchema schema, CachedType type) { // Is done all the time for XML to be able to get type name as the element name if not there was an attribute defined since earlier - var attributes = type.InheritedAttributes; + var attributes = type.GetAttributes(true); dynamic? xmlTypeAttribute = attributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlTypeAttribute"); var itemName = GetXmlItemName(type.OriginalType); @@ -73,14 +73,14 @@ public static void GenerateXmlObjectForProperty(this JsonSchemaProperty property if (propertySchema.IsArray) { - dynamic? xmlArrayAttribute = type.Attributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlArrayAttribute"); + dynamic? xmlArrayAttribute = type.GetContextOrTypeAttributes(true).FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlArrayAttribute"); if (xmlArrayAttribute != null) { xmlName = xmlArrayAttribute.ElementName; xmlNamespace = xmlArrayAttribute.Namespace; } - dynamic? xmlArrayItemsAttribute = type.Attributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlArrayItemAttribute"); + dynamic? xmlArrayItemsAttribute = type.GetContextOrTypeAttributes(true).FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlArrayItemAttribute"); if (xmlArrayItemsAttribute != null) { var xmlItemName = xmlArrayItemsAttribute.ElementName; @@ -92,14 +92,14 @@ public static void GenerateXmlObjectForProperty(this JsonSchemaProperty property xmlWrapped = true; } - dynamic? xmlElementAttribute = type.Attributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlElementAttribute"); + dynamic? xmlElementAttribute = type.GetContextOrTypeAttributes(true).FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlElementAttribute"); if (xmlElementAttribute != null) { xmlName = xmlElementAttribute.ElementName; xmlNamespace = xmlElementAttribute.Namespace; } - dynamic? xmlAttribute = type.Attributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlAttributeAttribute"); + dynamic? xmlAttribute = type.GetContextOrTypeAttributes(true).FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlAttributeAttribute"); if (xmlAttribute != null) { if (!string.IsNullOrEmpty(xmlAttribute.AttributeName)) @@ -117,7 +117,7 @@ public static void GenerateXmlObjectForProperty(this JsonSchemaProperty property // We need to ensure that the property name is preserved if (string.IsNullOrEmpty(xmlName) && propertySchema.Type == JsonObjectType.None) { - dynamic? xmlReferenceTypeAttribute = type.InheritedAttributes.FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlTypeAttribute"); + dynamic? xmlReferenceTypeAttribute = type.GetAttributes(true).FirstAssignableToTypeNameOrDefault("System.Xml.Serialization.XmlTypeAttribute"); if (xmlReferenceTypeAttribute != null) { xmlName = propertyName; diff --git a/src/NJsonSchema/JsonReferenceResolver.cs b/src/NJsonSchema/JsonReferenceResolver.cs index 543bf4070..ea2c17934 100644 --- a/src/NJsonSchema/JsonReferenceResolver.cs +++ b/src/NJsonSchema/JsonReferenceResolver.cs @@ -309,7 +309,7 @@ private async Task ResolveUrlReferenceWithAlreadyResolvedCheckAs foreach (var member in obj .GetType() .GetContextualAccessors() - .Where(p => p.AccessorType.GetInheritedAttribute() == null)) + .Where(p => p.IsAttributeDefined(true) == false)) { var pathSegment = member.GetName(); if (pathSegment == firstSegment) diff --git a/src/NJsonSchema/Visitors/AsyncJsonReferenceVisitorBase.cs b/src/NJsonSchema/Visitors/AsyncJsonReferenceVisitorBase.cs index 6073785bc..26a48185d 100644 --- a/src/NJsonSchema/Visitors/AsyncJsonReferenceVisitorBase.cs +++ b/src/NJsonSchema/Visitors/AsyncJsonReferenceVisitorBase.cs @@ -219,11 +219,11 @@ protected virtual async Task VisitAsync(object obj, string path, string? typeNam // Custom dictionary type with additional properties (OpenApiPathItem) var contextualType = obj.GetType().ToContextualType(); - if (contextualType.InheritedAttributes.OfType().Any()) + if (contextualType.IsAttributeDefined(true)) { foreach (var property in contextualType.Type.GetContextualProperties() .Where(p => p.MemberInfo.DeclaringType == contextualType.Type && - !p.GetContextAttributes().Any())) + !p.IsAttributeDefined(true))) { var value = property.GetValue(obj); if (value != null) diff --git a/src/NJsonSchema/Visitors/JsonReferenceVisitorBase.cs b/src/NJsonSchema/Visitors/JsonReferenceVisitorBase.cs index 5c5b23599..5be90a5e7 100644 --- a/src/NJsonSchema/Visitors/JsonReferenceVisitorBase.cs +++ b/src/NJsonSchema/Visitors/JsonReferenceVisitorBase.cs @@ -207,11 +207,12 @@ protected virtual void Visit(object obj, string path, string? typeNameHint, ISet // Custom dictionary type with additional properties (OpenApiPathItem) var contextualType = obj.GetType().ToContextualType(); - if (contextualType.GetInheritedAttributes().Any()) + if (contextualType.IsAttributeDefined(true)) { foreach (var property in contextualType.Type.GetContextualProperties()) { - if (property.MemberInfo.DeclaringType == contextualType.Type && !property.GetContextAttributes().Any()) + if (property.MemberInfo.DeclaringType == contextualType.Type && + !property.IsAttributeDefined(true)) { var value = property.GetValue(obj); if (value != null)