/// <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. type.Value.IsOpenApiNullable(out var underlyingType); var types = new Dictionary <string, Type>() { { type.Key, underlyingType } }; var schemas = new Dictionary <string, OpenApiSchema>(); var subAcceptor = new OpenApiSchemaAcceptor() { Types = types, Schemas = schemas, }; var collection = VisitorCollection.CreateInstance(); subAcceptor.Accept(collection, 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 visibility property. if (attributes.Any()) { var visibilityAttribute = attributes.OfType <OpenApiSchemaVisibilityAttribute>().SingleOrDefault(); if (!visibilityAttribute.IsNullOrDefault()) { var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName()); schema.Extensions.Add("x-ms-visibility", extension); } } instance.Schemas.Add(name, schema); }
/// <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.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 items = 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) }; items.Reference = reference; } instance.Schemas[name].Items = items; // 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 schema in schemasToBeAdded) { if (instance.RootSchemas.ContainsKey(schema.Key)) { continue; } instance.RootSchemas.Add(schema.Key, schema.Value); } }
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, }; var collection = VisitorCollection.CreateInstance(); subAcceptor.Accept(collection, 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.Type == "object" && p.Value.Format.IsNullOrWhiteSpace() && p.Value.Items.IsNullOrDefault() && p.Value.AdditionalProperties.IsNullOrDefault()) .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; }