/// <inheritdoc /> public override void Visit(IAcceptor acceptor, KeyValuePair <string, Type> type, NamingStrategy namingStrategy, params Attribute[] attributes) { var instance = acceptor as OpenApiSchemaAcceptor; if (instance.IsNullOrDefault()) { return; } // Gets the schema for the underlying type. var underlyingType = type.Value.GetUnderlyingType(); var types = new Dictionary <string, Type>() { { type.Key, underlyingType } }; var schemas = new Dictionary <string, OpenApiSchema>(); var subAcceptor = new OpenApiSchemaAcceptor() { Types = types, Schemas = schemas, }; subAcceptor.Accept(this.VisitorCollection, namingStrategy); // Adds the schema for the underlying type. var name = subAcceptor.Schemas.First().Key; var schema = subAcceptor.Schemas.First().Value; schema.Nullable = true; // Adds the extra properties. if (attributes.Any()) { Attribute attr = attributes.OfType <OpenApiPropertyDescriptionAttribute>().SingleOrDefault(); if (!attr.IsNullOrDefault()) { schema.Description = (attr as OpenApiPropertyDescriptionAttribute).Description; } attr = attributes.OfType <OpenApiSchemaVisibilityAttribute>().SingleOrDefault(); if (!attr.IsNullOrDefault()) { var extension = new OpenApiString((attr as OpenApiSchemaVisibilityAttribute).Visibility.ToDisplayName()); schema.Extensions.Add("x-ms-visibility", extension); } } instance.Schemas.Add(name, schema); }
private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary <string, PropertyInfo> properties, NamingStrategy namingStrategy) { var schemas = new Dictionary <string, OpenApiSchema>(); 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 <JsonPropertyAttribute>(inherit: false).IsNullOrDefault()) .Select(p => new KeyValuePair <string, JsonPropertyAttribute>(p.Key, p.Value.GetCustomAttribute <JsonPropertyAttribute>(inherit: false))) .Where(p => p.Value.Required == Required.Always || p.Value.Required == Required.DisallowNull); foreach (var attribute in jsonPropertyAttributes) { instance.Schemas[schemaName].Required.Add(attribute.Key); } var jsonRequiredAttributes = properties.Where(p => !p.Value.GetCustomAttribute <JsonRequiredAttribute>(inherit: false).IsNullOrDefault()) .Select(p => new KeyValuePair <string, JsonRequiredAttribute>(p.Key, p.Value.GetCustomAttribute <JsonRequiredAttribute>(inherit: false))); foreach (var attribute in jsonRequiredAttributes) { var attributeName = namingStrategy.GetPropertyName(attribute.Key, hasSpecifiedName: false); if (instance.Schemas[schemaName].Required.Contains(attributeName)) { continue; } instance.Schemas[schemaName].Required.Add(attributeName); } instance.Schemas[schemaName].Properties = subAcceptor.Schemas; // Adds schemas to the root. var schemasToBeAdded = subAcceptor.Schemas .Where(p => !instance.Schemas.Keys.Contains(p.Key)) .Where(p => p.Value.IsOpenApiSchemaObject()) .GroupBy(p => p.Value.Title) .Select(p => p.First()) .ToDictionary(p => p.Value.Title, p => p.Value); foreach (var schema in schemasToBeAdded.Where(p => p.Key != "jObject" && p.Key != "jToken")) { if (instance.RootSchemas.ContainsKey(schema.Key)) { continue; } 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 <string, OpenApiSchema>(p.Key, p.Value)); }) .ToDictionary(p => p.Key, p => p.Value); instance.Schemas[schemaName].Properties = subSchemas; }
/// <inheritdoc /> public override void Visit(IAcceptor acceptor, KeyValuePair <string, Type> type, NamingStrategy namingStrategy, params Attribute[] attributes) { var name = this.Visit(acceptor, name: type.Key, title: null, dataType: "object", dataFormat: null, attributes: attributes); if (name.IsNullOrWhiteSpace()) { return; } var instance = acceptor as OpenApiSchemaAcceptor; if (instance.IsNullOrDefault()) { return; } // Gets the schema for the underlying type. var underlyingType = type.Value.GetUnderlyingType(); var types = new Dictionary <string, Type>() { { underlyingType.GetOpenApiTypeName(namingStrategy), underlyingType } }; var schemas = new Dictionary <string, OpenApiSchema>(); var subAcceptor = new OpenApiSchemaAcceptor() { Types = types, RootSchemas = instance.RootSchemas, Schemas = schemas, }; subAcceptor.Accept(this.VisitorCollection, namingStrategy); var properties = subAcceptor.Schemas.First().Value; // Adds the reference to the schema for the underlying type. if (this.IsReferential(underlyingType)) { var reference = new OpenApiReference() { Type = ReferenceType.Schema, Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) }; properties.Reference = reference; } instance.Schemas[name].AdditionalProperties = properties; // Adds schemas to the root. var schemasToBeAdded = subAcceptor.Schemas .Where(p => !instance.Schemas.Keys.Contains(p.Key)) .Where(p => p.Value.Type == "object" && p.Value.Format.IsNullOrWhiteSpace() && p.Value.Items.IsNullOrDefault() && p.Value.AdditionalProperties.IsNullOrDefault()) .ToDictionary(p => p.Key, p => p.Value); if (!schemasToBeAdded.Any()) { return; } foreach (var schemaToBeAdded in schemasToBeAdded) { if (instance.RootSchemas.ContainsKey(schemaToBeAdded.Key)) { continue; } instance.RootSchemas.Add(schemaToBeAdded.Key, schemaToBeAdded.Value); } }
/// <inheritdoc /> public override void Visit(IAcceptor acceptor, KeyValuePair <string, Type> type, NamingStrategy namingStrategy, params Attribute[] attributes) { var name = this.Visit(acceptor, name: type.Key, title: null, dataType: "array", dataFormat: null, attributes: attributes); if (name.IsNullOrWhiteSpace()) { return; } var instance = acceptor as OpenApiSchemaAcceptor; if (instance.IsNullOrDefault()) { return; } // Gets the schema for the underlying type. var underlyingType = type.Value.GetUnderlyingType(); var types = new Dictionary <string, Type>() { { underlyingType.GetOpenApiReferenceId(underlyingType.IsOpenApiDictionary(), underlyingType.IsOpenApiArray(), namingStrategy), underlyingType } }; var schemas = new Dictionary <string, OpenApiSchema>(); OpenApiSchemaAcceptor subAcceptor; if (!this.visitedTypes.ContainsKey(underlyingType)) { subAcceptor = new OpenApiSchemaAcceptor() { Types = types, RootSchemas = instance.RootSchemas, Schemas = schemas, }; this.visitedTypes.Add(underlyingType, subAcceptor); subAcceptor.Accept(this.VisitorCollection, namingStrategy); } else { subAcceptor = this.visitedTypes[underlyingType]; } var items = subAcceptor.Schemas.First().Value; // Forces to remove the title value from the items attribute. items.Title = null; // Adds the reference to the schema for the underlying type. if (this.IsReferential(underlyingType)) { var reference = new OpenApiReference() { Type = ReferenceType.Schema, Id = underlyingType.GetOpenApiReferenceId(underlyingType.IsOpenApiDictionary(), underlyingType.IsOpenApiArray(), namingStrategy) }; items.Reference = reference; } instance.Schemas[name].Items = items; // Adds schemas to the root. var schemasToBeAdded = subAcceptor.Schemas .Where(p => p.Value.IsOpenApiSchemaObject() || p.Value.IsOpenApiSchemaArray() || p.Value.IsOpenApiSchemaDictionary() ) .ToDictionary(p => p.Key, p => p.Value); if (!schemasToBeAdded.Any()) { return; } foreach (var schema in schemasToBeAdded) { if (instance.RootSchemas.ContainsKey(schema.Key)) { continue; } instance.RootSchemas.Add(schema.Key, schema.Value); } }