diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs index b0fad9fc..515e96fb 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs @@ -20,6 +20,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors /// public class ObjectTypeVisitor : TypeVisitor { + private readonly Dictionary visitedTypes = new Dictionary(); + private readonly HashSet _noVisitableTypes = new HashSet { typeof(Guid), @@ -118,7 +120,25 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type, .Where(p => !p.ExistsCustomAttribute()) .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); - this.ProcessProperties(instance, name, properties, namingStrategy); + // Get subAcceptor + OpenApiSchemaAcceptor subAcceptor; + if (!this.visitedTypes.ContainsKey(type.Value)) + { + subAcceptor = new OpenApiSchemaAcceptor + { + Properties = properties, + RootSchemas = instance.RootSchemas, + Schemas = new Dictionary(), + }; + this.visitedTypes.Add(type.Value, subAcceptor); + subAcceptor.Accept(this.VisitorCollection, namingStrategy); + } + else + { + subAcceptor = this.visitedTypes[type.Value]; + } + + this.ProcessProperties(instance, subAcceptor, name, properties, namingStrategy); // Adds the reference. var reference = new OpenApiReference() @@ -172,19 +192,8 @@ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrat return this.PayloadVisit(dataType: "object", dataFormat: null); } - private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary properties, NamingStrategy namingStrategy) + private void ProcessProperties(IOpenApiSchemaAcceptor instance, IOpenApiSchemaAcceptor subAcceptor, string schemaName, Dictionary properties, NamingStrategy namingStrategy) { - var schemas = new Dictionary(); - - var subAcceptor = new OpenApiSchemaAcceptor() - { - Properties = properties, - RootSchemas = instance.RootSchemas, - Schemas = schemas, - }; - - subAcceptor.Accept(this.VisitorCollection, namingStrategy); - // Add required properties to schema. var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))) @@ -226,6 +235,7 @@ private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaNam var schemasToBeAdded = subAcceptor.Schemas .Where(p => !instance.Schemas.Keys.Contains(p.Key)) .Where(p => p.Value.IsOpenApiSchemaObject()) + .Where(p => !string.IsNullOrEmpty(p.Value.Title)) .GroupBy(p => p.Value.Title) .Select(p => p.First()) .ToDictionary(p => p.Value.Title, p => p.Value); @@ -239,17 +249,6 @@ private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaNam instance.RootSchemas.Add(schema.Key, schema.Value); } - - // Removes title of each property. - var subSchemas = instance.Schemas[schemaName].Properties; - subSchemas = subSchemas.Select(p => - { - p.Value.Title = null; - return new KeyValuePair(p.Key, p.Value); - }) - .ToDictionary(p => p.Key, p => p.Value); - - instance.Schemas[schemaName].Properties = subSchemas; } private IOpenApiAny GetExample(Type type, NamingStrategy namingStrategy = null)