Exemplo n.º 1
0
        private bool TryGetDiscriminatorFor(
            DataContract dataContract,
            SchemaRepository schemaRepository,
            IEnumerable <DataContract> knownTypesDataContracts,
            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).Reference.ReferenceV3);
            }

            return(true);
        }
Exemplo n.º 2
0
 private OpenApiSchema CreateDictionarySchema(DataContract dataContract, SchemaRepository schemaRepository)
 {
     if (dataContract.DictionaryKeys != null)
     {
         // This is a special case where the set of key values is known (e.g. if the key type is an enum)
         return(new OpenApiSchema
         {
             Type = "object",
             Properties = dataContract.DictionaryKeys.ToDictionary(
                 name => name,
                 name => GenerateSchema(dataContract.DictionaryValueType, schemaRepository)),
             AdditionalPropertiesAllowed = false,
         });
     }
     else
     {
         return(new OpenApiSchema
         {
             Type = "object",
             AdditionalPropertiesAllowed = true,
             AdditionalProperties = GenerateSchema(dataContract.DictionaryValueType, schemaRepository)
         });
     }
 }
Exemplo n.º 3
0
        private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository)
        {
            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>(),
                Required   = new SortedSet <string>(),
                AdditionalPropertiesAllowed = false
            };

            var applicableDataProperties = dataContract.ObjectProperties;

            if (_generatorOptions.UseAllOfForInheritance || _generatorOptions.UseOneOfForPolymorphism)
            {
                if (IsKnownSubType(dataContract, out var baseTypeDataContract))
                {
                    var baseTypeSchema = GenerateConcreteSchema(baseTypeDataContract, schemaRepository);

                    schema.AllOf.Add(baseTypeSchema);

                    applicableDataProperties = applicableDataProperties
                                               .Where(dataProperty => dataProperty.MemberInfo.DeclaringType == dataContract.UnderlyingType);
                }

                if (IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts))
                {
                    foreach (var knownTypeDataContract in knownTypesDataContracts)
                    {
                        // Ensure schema is generated for all known types
                        GenerateConcreteSchema(knownTypeDataContract, schemaRepository);
                    }

                    if (TryGetDiscriminatorFor(dataContract, schemaRepository, knownTypesDataContracts, out var discriminator))
                    {
                        schema.Properties.Add(discriminator.PropertyName, new OpenApiSchema {
                            Type = "string"
                        });
                        schema.Required.Add(discriminator.PropertyName);
                        schema.Discriminator = discriminator;
                    }
                }
            }

            foreach (var dataProperty in applicableDataProperties)
            {
                var customAttributes = dataProperty.MemberInfo?.GetInlineAndMetadataAttributes() ?? Enumerable.Empty <object>();

                if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any())
                {
                    continue;
                }

                schema.Properties[dataProperty.Name] = (dataProperty.MemberInfo != null)
                    ? GenerateSchemaForMember(dataProperty.MemberType, schemaRepository, dataProperty.MemberInfo, dataProperty)
                    : GenerateSchemaForType(dataProperty.MemberType, schemaRepository);

                if ((dataProperty.IsRequired || customAttributes.OfType <RequiredAttribute>().Any()) &&
                    !schema.Required.Contains(dataProperty.Name))
                {
                    schema.Required.Add(dataProperty.Name);
                }
            }

            if (dataContract.ObjectExtensionDataType != null)
            {
                schema.AdditionalPropertiesAllowed = true;
                schema.AdditionalProperties        = GenerateSchema(dataContract.ObjectExtensionDataType, schemaRepository);
            }

            return(schema);
        }
Exemplo n.º 4
0
        private OpenApiSchema GenerateConcreteSchema(DataContract dataContract, SchemaRepository schemaRepository)
        {
            if (TryGetCustomTypeMapping(dataContract.UnderlyingType, out Func <OpenApiSchema> customSchemaFactory))
            {
                return(customSchemaFactory());
            }

            if (dataContract.UnderlyingType.IsAssignableToOneOf(typeof(IFormFile), typeof(FileResult)))
            {
                return(new OpenApiSchema {
                    Type = "string", Format = "binary"
                });
            }

            Func <OpenApiSchema> schemaFactory;
            bool returnAsReference;

            switch (dataContract.DataType)
            {
            case DataType.Boolean:
            case DataType.Integer:
            case DataType.Number:
            case DataType.String:
            {
                schemaFactory     = () => CreatePrimitiveSchema(dataContract);
                returnAsReference = dataContract.UnderlyingType.IsEnum && !_generatorOptions.UseInlineDefinitionsForEnums;
                break;
            }

            case DataType.Array:
            {
                schemaFactory     = () => CreateArraySchema(dataContract, schemaRepository);
                returnAsReference = dataContract.UnderlyingType == dataContract.ArrayItemType;
                break;
            }

            case DataType.Dictionary:
            {
                schemaFactory     = () => CreateDictionarySchema(dataContract, schemaRepository);
                returnAsReference = dataContract.UnderlyingType == dataContract.DictionaryValueType;
                break;
            }

            case DataType.Object:
            {
                schemaFactory     = () => CreateObjectSchema(dataContract, schemaRepository);
                returnAsReference = true;
                break;
            }

            default:
            {
                schemaFactory     = () => new OpenApiSchema();
                returnAsReference = false;
                break;
            }
            }

            return(returnAsReference
                ? GenerateReferencedSchema(dataContract, schemaRepository, schemaFactory)
                : schemaFactory());
        }
Exemplo n.º 5
0
        private IList <OpenApiParameter> GenerateParameters(ServiceEntry apiDescription, SchemaRepository schemaRespository)
        {
            var applicableApiParameters = apiDescription.Parameters
                                          .Where(apiParam =>
            {
                return(apiParam != null &&
                       UtilityType.ConvertibleType.GetTypeInfo().IsAssignableFrom(apiParam?.ParameterType));
            });

            return(applicableApiParameters
                   .Select(apiParam => GenerateParameter(apiParam, schemaRespository))
                   .Union(new OpenApiParameter[] { CreateServiceKeyParameter(schemaRespository) }).ToList());
        }
Exemplo n.º 6
0
        private IList <OpenApiParameter> GenerateParameters(ApiDescription apiDescription, SchemaRepository schemaRespository)
        {
            var applicableApiParameters = apiDescription.ParameterDescriptions
                                          .Where(apiParam =>
            {
                return((!apiParam.IsFromBody() && !apiParam.IsFromForm()) &&
                       (!apiParam.CustomAttributes().OfType <BindNeverAttribute>().Any()) &&
                       (apiParam.ModelMetadata == null || apiParam.ModelMetadata.IsBindingAllowed));
            });

            return(applicableApiParameters
                   .Select(apiParam => GenerateParameter(apiParam, schemaRespository))
                   .ToList());
        }
Exemplo n.º 7
0
        private OpenApiPaths GeneratePaths(IEnumerable <ServiceEntry> apiDescriptions, SchemaRepository schemaRepository)
        {
            var apiDescriptionsByPath = apiDescriptions.OrderBy(p => p.RoutePath)
                                        .GroupBy(apiDesc => apiDesc.Descriptor.Id);

            var paths = new OpenApiPaths();

            foreach (var group in apiDescriptionsByPath)
            {
                var key = $"/{group.Min(p => p.RoutePath).TrimStart('/')}".Trim();
                if (!paths.ContainsKey(key))
                {
                    paths.Add(key,
                              new OpenApiPathItem
                    {
                        Operations = GenerateOperations(group, schemaRepository)
                    });
                }
                else
                {
                    paths.Add($"/{group.Min(p => $" {p.RoutePath}( {string.Join("_", p.Parameters.Select(m => m.ParameterType.Name))})")}",
                              new OpenApiPathItem
                    {
                        Operations = GenerateOperations(group, schemaRepository)
                    });
                }
            }
            ;

            return(paths);
        }
Exemplo n.º 8
0
        private OpenApiPaths GeneratePaths(IEnumerable <ApiDescription> apiDescriptions, SchemaRepository schemaRepository)
        {
            var apiDescriptionsByPath = apiDescriptions
                                        .OrderBy(_options.SortKeySelector)
                                        .GroupBy(apiDesc => apiDesc.RelativePathSansParameterConstraints());

            var paths = new OpenApiPaths();

            foreach (var group in apiDescriptionsByPath)
            {
                paths.Add($"/{group.Key}",
                          new OpenApiPathItem
                {
                    Operations = GenerateOperations(group, schemaRepository)
                });
            }
            ;

            return(paths);
        }