예제 #1
0
        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);
            }
        }
예제 #2
0
 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>
         {
예제 #3
0
        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;
            }
        }
예제 #4
0
        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;
            }
예제 #6
0
        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);
            }
        }
예제 #10
0
        // 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));
                }
            }
        }