public async Task ProcessAsync(DocumentProcessorContext context) { var schema = context.SchemaResolver.GetSchema(typeof(RuleAction), false); if (schema != null) { var discriminator = new OpenApiDiscriminator { JsonInheritanceConverter = new JsonInheritanceConverter("actionType", typeof(RuleAction)), PropertyName = "actionType" }; schema.DiscriminatorObject = discriminator; schema.Properties["actionType"] = new JsonProperty { Type = JsonObjectType.String, IsRequired = true }; foreach (var derived in RuleElementRegistry.Actions) { var derivedSchema = await context.SchemaGenerator.GenerateAsync(derived.Value.Type, context.SchemaResolver); var oldName = context.Document.Definitions.FirstOrDefault(x => x.Value == derivedSchema).Key; if (oldName != null) { context.Document.Definitions.Remove(oldName); context.Document.Definitions.Add(derived.Key, derivedSchema); } } RemoveFreezable(context, schema); } }
public static SwaggerGenOptions ConfigureForNetTopologySuite(this SwaggerGenOptions c) { c.DocumentFilter <DocumentFilter>(); c.MapType <Geometry>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new Uri("http://geojson.org/geojson-spec.html#geometry-objects"), }, Type = "object", Extensions = new Dictionary <string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(Geometry).FullName) }, Description = "GeoJSon geometry", Discriminator = new OpenApiDiscriminator { PropertyName = "type", }, Required = new HashSet <string> { "type" }, Properties = new Dictionary <string, OpenApiSchema> {
private static void BuildComponent(JsonSchema jsonSchema, ReadonlyList <DomainId>?schemaIds, Args args) { if (args.WithComponents) { var discriminator = new OpenApiDiscriminator { PropertyName = Component.Discriminator }; foreach (var schema in args.Components.Resolve(schemaIds).Values) { // Create a reference to give it a nice name in code generation. var(reference, actual) = args.Factory($"{schema.TypeName()}ComponentDto"); if (actual != null) { foreach (var field in schema.Fields.ForApi(args.WithHidden)) { var property = BuildProperty( field, args.Components, schema, args.Factory, args.WithHidden, args.WithComponents); if (property != null) { property.SetRequired(field.RawProperties.IsRequired); property.SetDescription(field); actual.Properties.Add(field.Name, property); } } } jsonSchema.OneOf.Add(reference); discriminator.Mapping[schema.Name] = reference; } jsonSchema.DiscriminatorObject = discriminator; if (discriminator.Mapping.Count > 0) { jsonSchema.Properties.Add(Component.Discriminator, JsonTypeBuilder.StringProperty(isRequired: true)); } } else { jsonSchema.AllowAdditionalProperties = true; } }
private void BuildComponent(JsonSchema jsonSchema, IField field, ImmutableList <DomainId>?schemaIds, Args args) { jsonSchema.Properties.Add(Component.Discriminator, SchemaBuilder.StringProperty(isRequired: true)); if (args.SchemaResolver != null) { var schemas = schemaIds?.Select(x => field.GetResolvedSchema(x)).NotNull() ?? Enumerable.Empty <Schema>(); var discriminator = new OpenApiDiscriminator { PropertyName = Component.Discriminator }; foreach (var schema in schemas) { var schemaName = $"{schema.TypeName()}ComponentDto"; var componentSchema = args.SchemaResolver(schemaName, () => { var nestedArgs = args.Increment(); var componentSchema = SchemaBuilder.Object(); foreach (var sharedField in schema.Fields.ForApi(nestedArgs.WithHiddenFields)) { var sharedProperty = sharedField.Accept(this, nestedArgs); if (sharedProperty != null) { sharedProperty.Description = sharedField.RawProperties.Hints; sharedProperty.SetRequired(sharedField.RawProperties.IsRequired); componentSchema.Properties.Add(sharedField.Name, sharedProperty); } } componentSchema.Properties.Add(Component.Discriminator, SchemaBuilder.StringProperty(isRequired: true)); return(componentSchema); }); jsonSchema.OneOf.Add(componentSchema); discriminator.Mapping[schemaName] = componentSchema; } jsonSchema.DiscriminatorObject = discriminator; } else { jsonSchema.AllowAdditionalProperties = true; } }
internal DerivedClassModel(string typeName, JsonSchema4 schema, OpenApiDiscriminator discriminator, TypeResolverBase resolver) { var mapping = discriminator.Mapping.SingleOrDefault(m => m.Value.ActualSchema == schema.ActualSchema); ClassName = resolver.GetOrGenerateTypeName(schema, typeName); IsAbstract = schema.ActualTypeSchema.IsAbstract; Discriminator = mapping.Value != null ? mapping.Key : !string.IsNullOrEmpty(typeName) ? typeName : ClassName; }
public static OpenApiDiscriminator LoadDiscriminator(ParseNode node) { var mapNode = node.CheckMapNode("discriminator"); var discriminator = new OpenApiDiscriminator(); foreach (var property in mapNode) { property.ParseField(discriminator, _discriminatorFixedFields, _discriminatorPatternFields); } return(discriminator); }
private bool TryGetDiscriminatorFor( DataContract dataContract, SchemaRepository schemaRepository, IEnumerable <DataContract> knownTypesDataContracts, ParameterInfo parameterInfo, out OpenApiDiscriminator discriminator) { discriminator = null; var discriminatorName = _generatorOptions.DiscriminatorNameSelector(dataContract.UnderlyingType) ?? dataContract.ObjectTypeNameProperty; if (discriminatorName == null) { return(false); } discriminator = new OpenApiDiscriminator { PropertyName = discriminatorName }; foreach (var knownTypeDataContract in knownTypesDataContracts) { var discriminatorValue = _generatorOptions.DiscriminatorValueSelector(knownTypeDataContract.UnderlyingType) ?? knownTypeDataContract.ObjectTypeNameValue; if (discriminatorValue == null) { continue; } discriminator.Mapping.Add(discriminatorValue, GenerateConcreteSchema(knownTypeDataContract, schemaRepository, parameterInfo).Reference.ReferenceV3); } return(true); }
private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext context, IEdmStructuredType structuredType, bool processBase, bool processExample, IEnumerable <IEdmStructuredType> derivedTypes = null) { Debug.Assert(context != null); Debug.Assert(structuredType != null); IOpenApiAny example = null; if (context.Settings.ShowSchemaExamples) { example = CreateStructuredTypePropertiesExample(context, structuredType); } if (context.Settings.EnableDiscriminatorValue && derivedTypes == null) { derivedTypes = context.Model.FindAllDerivedTypes(structuredType); } if (processBase && structuredType.BaseType != null) { // The x-ms-discriminator-value extension is added to structured types which are derived types. Dictionary <string, IOpenApiExtension> extension = null; if (context.Settings.EnableDiscriminatorValue && !derivedTypes.Any()) { extension = new Dictionary <string, IOpenApiExtension> { { Constants.xMsDiscriminatorValue, new OpenApiString("#" + structuredType.FullTypeName()) } }; } // A structured type with a base type is represented as a Schema Object // that contains the keyword allOf whose value is an array with two items: return(new OpenApiSchema { Extensions = extension, AllOf = new List <OpenApiSchema> { // 1. a JSON Reference to the Schema Object of the base type new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = structuredType.BaseType.FullTypeName() } }, // 2. a Schema Object describing the derived type context.CreateStructuredTypeSchema(structuredType, false, false, derivedTypes) }, AnyOf = null, OneOf = null, Properties = null, Example = example }); } else { // The discriminator object is added to structured types which have derived types. OpenApiDiscriminator discriminator = null; if (context.Settings.EnableDiscriminatorValue && derivedTypes.Any()) { Dictionary <string, string> mapping = derivedTypes .ToDictionary(x => $"#{x.FullTypeName()}", x => new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = x.FullTypeName() } }.Reference.ReferenceV3); discriminator = new OpenApiDiscriminator { PropertyName = Constants.OdataType, Mapping = mapping }; } // A structured type without a base type is represented as a Schema Object of type object OpenApiSchema schema = new() { Title = (structuredType as IEdmSchemaElement)?.Name, Type = "object", Discriminator = discriminator, // Each structural property and navigation property is represented // as a name/value pair of the standard OpenAPI properties object. Properties = context.CreateStructuredTypePropertiesSchema(structuredType), // make others null AllOf = null, OneOf = null, AnyOf = null }; if (context.Settings.EnableDiscriminatorValue) { if (!schema.Properties.TryAdd(Constants.OdataType, new OpenApiSchema() { Type = "string", Default = new OpenApiString("#" + structuredType.FullTypeName()), })) { throw new InvalidOperationException( $"Property {Constants.OdataType} is already present in schema {structuredType.FullTypeName()}; verify CSDL."); } schema.Required.Add(Constants.OdataType); } // It optionally can contain the field description, // whose value is the value of the unqualified annotation Core.Description of the structured type. if (structuredType.TypeKind == EdmTypeKind.Complex) { IEdmComplexType complex = (IEdmComplexType)structuredType; schema.Description = context.Model.GetDescriptionAnnotation(complex); } else if (structuredType.TypeKind == EdmTypeKind.Entity) { IEdmEntityType entity = (IEdmEntityType)structuredType; schema.Description = context.Model.GetDescriptionAnnotation(entity); } if (processExample) { schema.Example = example; } return(schema); } }
private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext context, IEdmStructuredType structuredType, bool processBase, bool processExample, IEnumerable <IEdmEntityType> derivedTypes = null) { Debug.Assert(context != null); Debug.Assert(structuredType != null); if (context.Settings.EnableDiscriminatorValue && derivedTypes == null) { derivedTypes = context.Model.FindDirectlyDerivedTypes(structuredType).OfType <IEdmEntityType>(); } if (processBase && structuredType.BaseType != null) { // The x-ms-discriminator-value extension is added to structured types which are derived types. Dictionary <string, IOpenApiExtension> extension = null; if (context.Settings.EnableDiscriminatorValue && !derivedTypes.Any()) { extension = new Dictionary <string, IOpenApiExtension> { { Constants.xMsDiscriminatorValue, new OpenApiString("#" + structuredType.FullTypeName()) } }; } // A structured type with a base type is represented as a Schema Object // that contains the keyword allOf whose value is an array with two items: return(new OpenApiSchema { Extensions = extension, AllOf = new List <OpenApiSchema> { // 1. a JSON Reference to the Schema Object of the base type new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = structuredType.BaseType.FullTypeName() } }, // 2. a Schema Object describing the derived type context.CreateStructuredTypeSchema(structuredType, false, false, derivedTypes) }, AnyOf = null, OneOf = null, Properties = null, Example = CreateStructuredTypePropertiesExample(context, structuredType) }); } else { // The discriminator object is added to structured types which have derived types. OpenApiDiscriminator discriminator = null; if (context.Settings.EnableDiscriminatorValue && derivedTypes.Any() && structuredType.BaseType != null) { discriminator = new OpenApiDiscriminator { PropertyName = "@odata.type" }; } // A structured type without a base type is represented as a Schema Object of type object OpenApiSchema schema = new OpenApiSchema { Title = (structuredType as IEdmSchemaElement)?.Name, Type = "object", Discriminator = discriminator, // Each structural property and navigation property is represented // as a name/value pair of the standard OpenAPI properties object. Properties = context.CreateStructuredTypePropertiesSchema(structuredType), // make others null AllOf = null, OneOf = null, AnyOf = null }; // It optionally can contain the field description, // whose value is the value of the unqualified annotation Core.Description of the structured type. if (structuredType.TypeKind == EdmTypeKind.Complex) { IEdmComplexType complex = (IEdmComplexType)structuredType; schema.Description = context.Model.GetDescriptionAnnotation(complex); } else if (structuredType.TypeKind == EdmTypeKind.Entity) { IEdmEntityType entity = (IEdmEntityType)structuredType; schema.Description = context.Model.GetDescriptionAnnotation(entity); } if (processExample) { schema.Example = CreateStructuredTypePropertiesExample(context, structuredType); } return(schema); } }
// add more rule. /// <summary> /// Checks if the schemas in the list contain a property with the property name specified by the discriminator. /// </summary> private static void ValidateSchemaListDiscriminator(IValidationContext context, string ruleName, IList <OpenApiSchema> schemas, OpenApiDiscriminator discriminator) { foreach (var schema in schemas) { if (schema.Reference != null && !schema.Properties.ContainsKey(discriminator.PropertyName)) { context.CreateError(ruleName, string.Format(SRResource.Validation_CompositeSchemaMustContainPropertySpecifiedInTheDiscriminator, schema.Reference.Id, discriminator.PropertyName)); } if (schema.Reference != null && !schema.Required.Contains(discriminator.PropertyName)) { context.CreateError(ruleName, string.Format(SRResource.Validation_CompositeSchemaRequiredFieldListMustContainThePropertySpecifiedInTheDiscriminator, schema.Reference.Id, discriminator.PropertyName)); } } }