public override void ResolveReferences(OpenApiComponents components) { base.ResolveReferences(components); Schema = Schema?.Resolve(components); }
public override void Visit(OpenApiSchema schema) { Locations.Add(this.PathString); }
public static bool IsOneOf(this OpenApiSchema schema) { return(schema?.OneOf?.Any() ?? false); }
public bool CanValidate(OpenApiSchema schema) => schema.AllOf != null && schema.AllOf.Any();
private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext context, IEdmStructuredType structuredType, bool processBase, bool processExample) { Debug.Assert(context != null); Debug.Assert(structuredType != null); if (processBase && structuredType.BaseType != null) { // 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 { 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) }, AnyOf = null, OneOf = null, Properties = null, Example = CreateStructuredTypePropertiesExample(structuredType) }); } else { // 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", // 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(structuredType); } return(schema); } }
private OpenApiSchema GenerateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository) { var schema = new OpenApiSchema { Type = "object", Properties = new Dictionary <string, OpenApiSchema>(), Required = new SortedSet <string>(), AdditionalPropertiesAllowed = false }; // If it's a baseType with known subTypes, add the discriminator property if (_generatorOptions.GeneratePolymorphicSchemas && _generatorOptions.SubTypesResolver(dataContract.UnderlyingType).Any()) { var discriminatorName = _generatorOptions.DiscriminatorSelector(dataContract.UnderlyingType); if (!schema.Properties.ContainsKey(discriminatorName)) { schema.Properties.Add(discriminatorName, new OpenApiSchema { Type = "string" }); } schema.Required.Add(discriminatorName); schema.Discriminator = new OpenApiDiscriminator { PropertyName = discriminatorName }; } foreach (var dataProperty in dataContract.Properties ?? Enumerable.Empty <DataProperty>()) { var customAttributes = dataProperty.MemberInfo?.GetInlineOrMetadataTypeAttributes() ?? Enumerable.Empty <object>(); if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any()) { continue; } schema.Properties[dataProperty.Name] = GeneratePropertySchema(dataProperty, schemaRepository); if (dataProperty.IsRequired || customAttributes.OfType <RequiredAttribute>().Any()) { schema.Required.Add(dataProperty.Name); } } if (dataContract.AdditionalPropertiesType != null) { schema.AdditionalPropertiesAllowed = true; schema.AdditionalProperties = GenerateSchema(dataContract.AdditionalPropertiesType, schemaRepository); } // If it's a known subType, reference the baseType for inheritied properties if ( _generatorOptions.GeneratePolymorphicSchemas && (dataContract.UnderlyingType.BaseType != null) && _generatorOptions.SubTypesResolver(dataContract.UnderlyingType.BaseType).Contains(dataContract.UnderlyingType)) { var basedataContract = _dataContractResolver.GetDataContractForType(dataContract.UnderlyingType.BaseType); var baseSchemaReference = GenerateReferencedSchema(basedataContract, schemaRepository); var baseSchema = schemaRepository.Schemas[baseSchemaReference.Reference.Id]; foreach (var basePropertyName in baseSchema.Properties.Keys) { schema.Properties.Remove(basePropertyName); } return(new OpenApiSchema { AllOf = new List <OpenApiSchema> { baseSchemaReference, schema } }); } return(schema); }
public static void AppendVarDataModelOrListOfModel( int indentSpaces, StringBuilder sb, EndpointMethodMetadata endpointMethodMetadata, OpenApiSchema schema, HttpStatusCode httpStatusCode, SchemaMapLocatedAreaType locatedAreaType, KeyValuePair <string, OpenApiSchema>?badPropertySchema = null, bool asJsonBody = false, int maxItemsForList = 3, int depthHierarchy = 0, int maxDepthHierarchy = 2) { ArgumentNullException.ThrowIfNull(endpointMethodMetadata); var trailingChar = TrailingCharType.SemiColon; if (asJsonBody) { trailingChar = TrailingCharType.None; } switch (locatedAreaType) { case SchemaMapLocatedAreaType.Parameter: break; case SchemaMapLocatedAreaType.RequestBody: if (schema.IsTypeArray()) { var indentSpacesForData = indentSpaces; if (asJsonBody) { sb.AppendLine(indentSpaces, "var sb = new StringBuilder();"); indentSpacesForData -= 4; } if (schema.HasItemsWithFormatTypeBinary()) { if (asJsonBody) { throw new NotSupportedException("JSON not supported when RequestBody is type Array and format type is Binary."); } sb.AppendLine(indentSpaces, "var data = GetTestFiles();"); } else { AppendVarDataEqualNewListOfModel( indentSpacesForData, sb, endpointMethodMetadata, new KeyValuePair <string, OpenApiSchema>("data", schema), trailingChar, maxItemsForList, depthHierarchy, maxDepthHierarchy, badPropertySchema, asJsonBody); } if (asJsonBody) { sb.AppendLine(indentSpaces, "var data = sb.ToString();"); } } else { if (asJsonBody) { sb.AppendLine(indentSpaces, "var sb = new StringBuilder();"); } else { GenerateXunitTestPartsHelper.AppendPartVarDataEqualNew(12, sb); } var modelName = schema.GetModelName(); AppendModel( indentSpaces, sb, endpointMethodMetadata, modelName, schema, trailingChar, 0, maxItemsForList, depthHierarchy, maxDepthHierarchy, badPropertySchema, asJsonBody); if (asJsonBody) { sb.AppendLine(indentSpaces, "var data = sb.ToString();"); } } break; case SchemaMapLocatedAreaType.Response: var contractReturnTypeName = endpointMethodMetadata.ContractReturnTypeNames.First(x => x.StatusCode == httpStatusCode); if (GenerateXunitTestPartsHelper.IsListKind(contractReturnTypeName.FullModelName)) { AppendVarDataEqualNewListOfModel( indentSpaces, sb, endpointMethodMetadata, new KeyValuePair <string, OpenApiSchema>("data", contractReturnTypeName.Schema !), trailingChar, maxItemsForList, depthHierarchy, maxDepthHierarchy, badPropertySchema, asJsonBody); } else { GenerateXunitTestPartsHelper.AppendPartVarDataEqualNew(12, sb); AppendModel( indentSpaces, sb, endpointMethodMetadata, contractReturnTypeName.FullModelName, contractReturnTypeName.Schema !, trailingChar, 0, maxItemsForList, depthHierarchy, maxDepthHierarchy, badPropertySchema, asJsonBody); } break; default: throw new ArgumentOutOfRangeException(nameof(locatedAreaType), locatedAreaType, message: null); } }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = new OpenApiSchema { // $ref returns string for the Uri? Type = "string" }; if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { var properties = new Dictionary <string, OpenApiSchema> { { "value", new OpenApiSchema { Type = "array", Items = schema } } }; if (Context.Settings.EnablePagination) { properties.Add( "@odata.nextLink", new OpenApiSchema { Type = "string" }); } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved navigation property links", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = new OpenApiSchema { Title = "Collection of links of " + NavigationProperty.ToEntityType().Name, Type = "object", Properties = properties } } } } } } }; } else { IDictionary <string, OpenApiLink> links = null; if (Context.Settings.ShowLinks) { string operationId = GetOperationId(); links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name, entityKind: NavigationProperty.PropertyKind.ToString(), parameters: operation.Parameters, navPropOperationId: operationId); } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved navigation property link", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } }, Links = links } } }; } operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse()); base.SetResponses(operation); }
public bool CanValidate(OpenApiSchema schema) => schema.Type == "null";
private void ParseDefinitions(IDictionary <string, OpenApiSchema> schemas, Type schemaType, string route, string verb) { if (IsSwaggerScalarType(schemaType) || schemaType.ExcludesFeature(Feature.Metadata)) { return; } var schemaId = GetSchemaTypeName(schemaType); if (schemas.ContainsKey(schemaId)) { return; } var schema = GetDictionarySchema(schemas, schemaType, route, verb) ?? GetKeyValuePairSchema(schemas, schemaType, route, verb) ?? GetListSchema(schemas, schemaType, route, verb); bool parseProperties = false; if (schema == null) { schema = new OpenApiSchema { Type = OpenApiType.Object, Description = schemaType.GetDescription() ?? GetSchemaTypeName(schemaType), Properties = new OrderedDictionary <string, OpenApiProperty>() }; parseProperties = schemaType.IsUserType(); } schemas[schemaId] = schema; var properties = schemaType.GetProperties(); // Order schema properties by DataMember.Order if [DataContract] and [DataMember](s) defined // Ordering defined by: http://msdn.microsoft.com/en-us/library/ms729813.aspx var dataContractAttr = schemaType.FirstAttribute <DataContractAttribute>(); if (dataContractAttr != null && properties.Any(prop => prop.IsDefined(typeof(DataMemberAttribute), true))) { var typeOrder = new List <Type> { schemaType }; var baseType = schemaType.BaseType(); while (baseType != null) { typeOrder.Add(baseType); baseType = baseType.BaseType(); } var propsWithDataMember = properties.Where(prop => prop.IsDefined(typeof(DataMemberAttribute), true)); var propDataMemberAttrs = properties.ToDictionary(prop => prop, prop => prop.FirstAttribute <DataMemberAttribute>()); properties = propsWithDataMember .OrderBy(prop => propDataMemberAttrs[prop].Order) // Order by DataMember.Order .ThenByDescending(prop => typeOrder.IndexOf(prop.DeclaringType)) // Then by BaseTypes First .ThenBy(prop => // Then by [DataMember].Name / prop.Name { var name = propDataMemberAttrs[prop].Name; return(name.IsNullOrEmpty() ? prop.Name : name); }).ToArray(); } if (parseProperties) { foreach (var prop in properties) { if (prop.HasAttribute <IgnoreDataMemberAttribute>()) { continue; } var apiMembers = prop .AllAttributes <ApiMemberAttribute>() .OrderByDescending(attr => attr.Route) .ToList(); var apiDoc = apiMembers .Where(attr => string.IsNullOrEmpty(verb) || string.IsNullOrEmpty(attr.Verb) || (verb ?? "").Equals(attr.Verb)) .Where(attr => string.IsNullOrEmpty(route) || string.IsNullOrEmpty(attr.Route) || (route ?? "").StartsWith(attr.Route)) .FirstOrDefault(attr => attr.ParameterType == "body" || attr.ParameterType == "model"); if (apiMembers.Any(x => x.ExcludeInSchema)) { continue; } var schemaProp = GetOpenApiProperty(schemas, prop.PropertyType, route, verb); schemaProp.Description = prop.GetDescription() ?? apiDoc?.Description; var propAttr = prop.FirstAttribute <ApiMemberAttribute>(); if (propAttr != null) { if (propAttr.DataType != null) { schemaProp.Type = propAttr.DataType; } if (propAttr.Format != null) { schemaProp.Format = propAttr.Format; } } var allowableValues = prop.FirstAttribute <ApiAllowableValuesAttribute>(); if (allowableValues != null) { schemaProp.Enum = GetEnumValues(allowableValues); } SchemaPropertyFilter?.Invoke(schemaProp); schema.Properties[GetSchemaPropertyName(prop)] = schemaProp; } } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var typeName = context.Type.Name; schema.Example = !Schemas.ContainsKey(typeName) ? null : Schemas[typeName]; }
public static IOpenApiAny Resolve(IOpenApiAny any, OpenApiSchema schema = null) { if (any is OpenApiArray arrayAny) { var newArray = new OpenApiArray(); foreach (var element in arrayAny) { newArray.Add(Resolve(element, schema?.Items)); } return(newArray); } if (any is OpenApiObject objectAny) { var newObject = new OpenApiObject(); foreach (var propertyName in objectAny.Keys.ToList()) { if (schema?.Properties != null && schema.Properties.ContainsKey(propertyName)) { newObject[propertyName] = Resolve(objectAny[propertyName], schema.Properties[propertyName]); } else if (schema?.AdditionalProperties != null && schema.AdditionalProperties is OpenApiSchema ss) { newObject[propertyName] = Resolve(objectAny[propertyName], ss); } } return(newObject); } if (!(any is OpenApiString)) { return(any); // already a non-string OpenApiAny } var value = ((OpenApiString)any).Value; if (((OpenApiString)any).Quoted) // quoted string { if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue)) { return(new OpenApiDateTime(dateTimeValue)); } return(any); // actual type is OpenApiString } if (value == null) { return(new OpenApiNull()); } if (schema?.Type == null) { if (value == "true") { return(new OpenApiBoolean(true)); } if (value == "false") { return(new OpenApiBoolean(false)); } if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) { return(new OpenApiInt32(intValue)); } if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longValue)) { return(new OpenApiInt64(longValue)); } if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue)) { return(new OpenApiDouble(doubleValue)); } if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue)) { return(new OpenApiDateTime(dateTimeValue)); } } else { if (schema.Type == "integer") { if (schema.Format != null && schema.Format == "int64") { if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longValue)) { return(new OpenApiInt64(longValue)); } } else { if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) { return(new OpenApiInt32(intValue)); } } } if (schema.Type == "number") { if (schema.Format != null && schema.Format == "float") { if (float.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var floatValue)) { return(new OpenApiFloat(floatValue)); } } else { if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue)) { return(new OpenApiDouble(doubleValue)); } } } if (schema.Type == "string") { if (schema.Format != null && schema.Format == "byte") { try { return(new OpenApiByte(Convert.FromBase64String(value))); } catch (FormatException) { } } else if (schema.Format != null && schema.Format == "binary") { try { return(new OpenApiBinary(Encoding.UTF8.GetBytes(value))); } catch (EncoderFallbackException) { } } else if (schema.Format != null && (schema.Format == "date" || schema.Format == "date-time")) { if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateValue)) { return(new OpenApiDate(dateValue.Date)); } } else if (schema.Format != null && schema.Format == "password") { return(new OpenApiPassword(value)); } else { return(new OpenApiString(value)); } } if (schema.Type == "boolean") { if (bool.TryParse(value, out var booleanValue)) { return(new OpenApiBoolean(booleanValue)); } } } return(any); }
/// <summary> /// Create a <see cref="OpenApiSchema"/> for a <see cref="IEdmPrimitiveType"/>. /// </summary> /// <param name="context">The OData context.</param> /// <param name="primitiveType">The Edm primitive type.</param> /// <returns>The created <see cref="OpenApiSchema"/>.</returns> public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveType primitiveType) { Utils.CheckArgumentNull(context, nameof(context)); Utils.CheckArgumentNull(primitiveType, nameof(primitiveType)); // Spec has different configure for double, AnyOf or OneOf? OpenApiSchema schema = new OpenApiSchema { AllOf = null, OneOf = null, AnyOf = null }; switch (primitiveType.PrimitiveKind) { case EdmPrimitiveTypeKind.Binary: // binary schema.Type = "string"; schema.Format = "base64url"; break; case EdmPrimitiveTypeKind.Boolean: // boolean schema.Type = "boolean"; schema.Default = new OpenApiBoolean(false); break; case EdmPrimitiveTypeKind.Byte: // byte schema.Type = "integer"; schema.Format = "uint8"; break; case EdmPrimitiveTypeKind.DateTimeOffset: // datetime offset schema.Type = "string"; schema.Format = "date-time"; schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$"; break; case EdmPrimitiveTypeKind.Decimal: // decimal if (context.Settings.IEEE754Compatible) { schema.AnyOf = new List <OpenApiSchema> { new OpenApiSchema { Type = "number" }, new OpenApiSchema { Type = "string" }, }; } else { schema.Type = "number"; } schema.Format = "decimal"; break; case EdmPrimitiveTypeKind.Double: // double if (context.Settings.IEEE754Compatible) { schema.AnyOf = new List <OpenApiSchema> { new OpenApiSchema { Type = "number" }, new OpenApiSchema { Type = "string" }, new OpenApiSchema { Enum = new List <IOpenApiAny> { new OpenApiString("-INF"), new OpenApiString("INF"), new OpenApiString("NaN") } } }; } else { schema.Type = "number"; } schema.Format = "double"; break; case EdmPrimitiveTypeKind.Single: // single if (context.Settings.IEEE754Compatible) { schema.AnyOf = new List <OpenApiSchema> { new OpenApiSchema { Type = "number" }, new OpenApiSchema { Type = "string" }, new OpenApiSchema { Enum = new List <IOpenApiAny> { new OpenApiString("-INF"), new OpenApiString("INF"), new OpenApiString("NaN") } } }; } else { schema.Type = "number"; } schema.Format = "float"; break; case EdmPrimitiveTypeKind.Guid: // guid schema.Type = "string"; schema.Format = "uuid"; schema.Pattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"; break; case EdmPrimitiveTypeKind.Int16: schema.Type = "integer"; schema.Format = "int16"; schema.Minimum = Int16.MinValue; // -32768 schema.Maximum = Int16.MaxValue; // 32767 break; case EdmPrimitiveTypeKind.Int32: schema.Type = "integer"; schema.Format = "int32"; schema.Minimum = Int32.MinValue; // -2147483648 schema.Maximum = Int32.MaxValue; // 2147483647 break; case EdmPrimitiveTypeKind.Int64: if (context.Settings.IEEE754Compatible) { schema.AnyOf = new List <OpenApiSchema> { new OpenApiSchema { Type = "integer" }, new OpenApiSchema { Type = "string" } }; } else { schema.Type = "integer"; } schema.Format = "int64"; break; case EdmPrimitiveTypeKind.SByte: schema.Type = "integer"; schema.Format = "int8"; schema.Minimum = SByte.MinValue; // -128 schema.Maximum = SByte.MaxValue; // 127 break; case EdmPrimitiveTypeKind.String: // string schema.Type = "string"; break; case EdmPrimitiveTypeKind.Stream: // stream schema.Type = "string"; schema.Format = "base64url"; break; case EdmPrimitiveTypeKind.Duration: // duration schema.Type = "string"; schema.Format = "duration"; schema.Pattern = "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$"; break; case EdmPrimitiveTypeKind.Date: schema.Type = "string"; schema.Format = "date"; schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$"; break; case EdmPrimitiveTypeKind.TimeOfDay: schema.Type = "string"; schema.Format = "time"; schema.Pattern = "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$"; break; case EdmPrimitiveTypeKind.Geography: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.Geography" }; break; case EdmPrimitiveTypeKind.GeographyPoint: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyPoint" }; break; case EdmPrimitiveTypeKind.GeographyLineString: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyLineString" }; break; case EdmPrimitiveTypeKind.GeographyPolygon: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyPolygon" }; break; case EdmPrimitiveTypeKind.GeographyCollection: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyCollection" }; break; case EdmPrimitiveTypeKind.GeographyMultiPolygon: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyMultiPolygon" }; break; case EdmPrimitiveTypeKind.GeographyMultiLineString: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyMultiLineString" }; break; case EdmPrimitiveTypeKind.GeographyMultiPoint: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeographyMultiPoint" }; break; case EdmPrimitiveTypeKind.Geometry: // Geometry schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.Geometry" }; break; case EdmPrimitiveTypeKind.GeometryPoint: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryPoint" }; break; case EdmPrimitiveTypeKind.GeometryLineString: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryLineString" }; break; case EdmPrimitiveTypeKind.GeometryPolygon: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryPolygon" }; break; case EdmPrimitiveTypeKind.GeometryCollection: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryCollection" }; break; case EdmPrimitiveTypeKind.GeometryMultiPolygon: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryMultiPolygon" }; break; case EdmPrimitiveTypeKind.GeometryMultiLineString: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryMultiLineString" }; break; case EdmPrimitiveTypeKind.GeometryMultiPoint: schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Edm.GeometryMultiPoint" }; break; case EdmPrimitiveTypeKind.None: default: throw new OpenApiException(String.Format(SRResource.NotSupportedEdmTypeKind, primitiveType.PrimitiveKind)); } return(schema); }
public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, OpenApiSchema expected) { var result = this._visitor.ParameterVisit(objectType, this._strategy); result.Should().Be(expected); }
/// <summary> /// Fetches the value of "param" tags from xml documentation with in valus of "body" /// and populates operation's request body. /// </summary> /// <param name="operation">The operation to be updated.</param> /// <param name="element">The xml element representing an operation in the annotation xml.</param> /// <param name="settings">The operation filter settings.</param> /// <returns>The list of generation errors, if any produced when processing the filter.</returns> /// <remarks> /// Care should be taken to not overwrite the existing value in Operation if already present. /// This guarantees the predictable behavior that the first tag in the XML will be respected. /// It also guarantees that common annotations in the config file do not overwrite the /// annotations in the main documentation. /// </remarks> public IList <GenerationError> Apply( OpenApiOperation operation, XElement element, OperationFilterSettings settings) { var generationErrors = new List <GenerationError>(); try { var bodyElements = element.Elements() .Where( p => p.Name == KnownXmlStrings.Param && p.Attribute(KnownXmlStrings.In)?.Value == KnownXmlStrings.Body) .ToList(); var generationContext = settings.GenerationContext; foreach (var bodyElement in bodyElements) { var name = bodyElement.Attribute(KnownXmlStrings.Name)?.Value.Trim(); var mediaType = bodyElement.Attribute(KnownXmlStrings.Type)?.Value ?? "application/json"; var description = bodyElement.GetDescriptionTextFromLastTextNode(); var allListedTypes = bodyElement.GetListedTypes(); if (!allListedTypes.Any()) { throw new InvalidRequestBodyException( string.Format(SpecificationGenerationMessages.MissingSeeCrefTag, name)); } var crefKey = allListedTypes.ToCrefKey(); OpenApiSchema schema = new OpenApiSchema(); if (generationContext.CrefToSchemaMap.ContainsKey(crefKey)) { var schemaInfo = generationContext.CrefToSchemaMap[crefKey]; if (schemaInfo.Error != null) { generationErrors.Add(schemaInfo.Error); return(generationErrors); } schemaInfo.Schema.CopyInto(schema); } var examples = bodyElement.ToOpenApiExamples( generationContext.CrefToFieldValueMap, generationErrors); var schemaReferenceDefaultVariant = generationContext .VariantSchemaReferenceMap[DocumentVariantInfo.Default]; if (examples.Count > 0) { var firstExample = examples.First().Value?.Value; if (firstExample != null) { // In case a schema is a reference, find that schema object in schema registry // and update the example. if (schema.Reference != null) { if (schemaReferenceDefaultVariant.ContainsKey(schema.Reference.Id)) { schemaReferenceDefaultVariant[schema.Reference.Id].Example = firstExample; } } else { schema.Example = firstExample; } } } if (operation.RequestBody == null) { operation.RequestBody = new OpenApiRequestBody { Description = description.RemoveBlankLines(), Content = { [mediaType] = new OpenApiMediaType { Schema = schema } }, Required = true }; } else { if (string.IsNullOrWhiteSpace(operation.RequestBody.Description)) { operation.RequestBody.Description = description.RemoveBlankLines(); } if (!operation.RequestBody.Content.ContainsKey(mediaType)) { operation.RequestBody.Content[mediaType] = new OpenApiMediaType { Schema = schema }; } else { if (!operation.RequestBody.Content[mediaType].Schema.AnyOf.Any()) { var existingSchema = operation.RequestBody.Content[mediaType].Schema; var newSchema = new OpenApiSchema(); newSchema.AnyOf.Add(existingSchema); operation.RequestBody.Content[mediaType].Schema = newSchema; } operation.RequestBody.Content[mediaType].Schema.AnyOf.Add(schema); } } if (examples.Count > 0) { if (operation.RequestBody.Content[mediaType].Examples.Any()) { examples.CopyInto(operation.RequestBody.Content[mediaType].Examples); } else { operation.RequestBody.Content[mediaType].Examples = examples; } } } } catch (Exception ex) { generationErrors.Add( new GenerationError { Message = ex.Message, ExceptionType = ex.GetType().Name }); } return(generationErrors); }
private static OpenApiResponse GetResponse(string returnDescStr) { if (string.IsNullOrEmpty(returnDescStr) || !returnDescStr.StartsWith('{')) { var resp = new OpenApiResponse { Description = "Success", Content = new Dictionary <string, OpenApiMediaType>() }; resp.Content.Add("application/json", new OpenApiMediaType { Schema = new OpenApiSchema { Type = "object", Default = new OpenApiString(returnDescStr) } }); return(resp); } var returnDesc = JsonConvert.DeserializeObject <JimuServiceReturnDesc>(TypeHelper.ReplaceTypeToJsType(returnDescStr)); var response = new OpenApiResponse { Description = string.IsNullOrEmpty(returnDesc.Comment) ? "Success" : returnDesc.Comment, Content = new Dictionary <string, OpenApiMediaType>() }; var isVoid = returnDesc.ReturnType == "System.Void"; if (isVoid) { return(response); } var isObject = TypeHelper.CheckIsObject(returnDesc.ReturnType); var isArray = TypeHelper.CheckIsArray(returnDesc.ReturnType); var schema = new OpenApiSchema { Type = returnDesc.ReturnType }; if ((isObject || isArray) && returnDesc.Properties != null && returnDesc.Properties.Any()) { if (isArray) { schema = new OpenApiSchema { Type = "array", Title = returnDesc.Comment, Description = returnDesc.Comment, Items = new OpenApiSchema { Properties = _schemaFactory.GetProperties(returnDesc.Properties) } }; } else { schema = new OpenApiSchema { Type = "object", Title = returnDesc.Comment, Description = returnDesc.Comment, Properties = _schemaFactory.GetProperties(returnDesc.Properties) }; } } response.Content.Add("application/json", new OpenApiMediaType { Schema = schema }); return(response); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { throw new System.NotImplementedException(); }
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.IsAssignableFrom(baseTypeDataContract.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); }
public static void AppendModel( int indentSpaces, StringBuilder sb, EndpointMethodMetadata endpointMethodMetadata, string modelName, OpenApiSchema schema, TrailingCharType trailingChar, int itemNumber, int maxItemsForList, int depthHierarchy, int maxDepthHierarchy, KeyValuePair <string, OpenApiSchema>?badPropertySchema, bool asJsonBody, string?parentModelNameToJsonBody = null) { ArgumentNullException.ThrowIfNull(sb); ArgumentNullException.ThrowIfNull(schema); var countString = 1; var renderModelName = OpenApiDocumentSchemaModelNameHelper.EnsureModelNameWithNamespaceIfNeeded(endpointMethodMetadata, modelName); var jsonSpaces = string.Empty.PadLeft(depthHierarchy * 2); if (asJsonBody) { sb.AppendLine( indentSpaces, string.IsNullOrEmpty(parentModelNameToJsonBody) ? GenerateXunitTestPartsHelper.WrapInStringBuilderAppendLine($"{jsonSpaces}{{") : GenerateXunitTestPartsHelper.WrapInStringBuilderAppendLine($"{jsonSpaces}\\\"{parentModelNameToJsonBody}\\\": {{")); } else { sb.AppendLine(renderModelName); sb.AppendLine(indentSpaces, "{"); } foreach (var schemaProperty in schema.Properties) { var trailingCharForProperty = GenerateXunitTestPartsHelper.GetTrailingCharForProperty(asJsonBody, schemaProperty, schema.Properties); var useForBadRequest = badPropertySchema is not null && schemaProperty.Key.Equals(badPropertySchema.Value.Key, StringComparison.Ordinal); var dataType = schemaProperty.Value.GetDataType(); var propertyValueGenerated = GenerateXunitTestPartsHelper.PropertyValueGenerator( schemaProperty, endpointMethodMetadata.ComponentsSchemas, useForBadRequest, itemNumber, customValue: null); if ("NEW-INSTANCE-LIST".Equals(propertyValueGenerated, StringComparison.Ordinal)) { AppendDataEqualNewListOfModel( indentSpaces + 4, sb, endpointMethodMetadata, schemaProperty, trailingCharForProperty, maxItemsForList, depthHierarchy + 1, maxDepthHierarchy, badPropertySchema, asJsonBody); } else if ("NEW-INSTANCE".Equals(propertyValueGenerated, StringComparison.Ordinal)) { AppendModelComplexProperty( indentSpaces, sb, endpointMethodMetadata, schemaProperty, dataType, trailingCharForProperty, itemNumber, maxItemsForList, depthHierarchy + 1, maxDepthHierarchy, badPropertySchema, asJsonBody); } else { var countResult = GenerateXunitTestPartsHelper.AppendModelSimpleProperty( indentSpaces, sb, endpointMethodMetadata, schemaProperty, dataType, schema.Required.Contains(schemaProperty.Key), propertyValueGenerated, countString, asJsonBody, depthHierarchy, trailingCharForProperty); if (countResult > 1) { countString += 1; } } } sb.AppendLine( indentSpaces, asJsonBody ? GenerateXunitTestPartsHelper.WrapInStringBuilderAppendLine($"{jsonSpaces}}}{GenerateCodeHelper.GetTrailingChar(trailingChar)}") : $"}}{GenerateCodeHelper.GetTrailingChar(trailingChar)}"); }
private static void CompareOpenApiSchema(List <Change> changes, OpenApiSchema before, OpenApiSchema after, ChangeType changeType) { // TODO: Flesh out and check for nulls (both nulls) }
private OpenApiSchema GenerateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository) { var schema = new OpenApiSchema { Type = "object", Properties = new Dictionary <string, OpenApiSchema>(), Required = new SortedSet <string>(), AdditionalPropertiesAllowed = false }; // By default, all properties will be defined in this schema // However, if "Inheritance" behavior is enabled (see below), this set will be reduced to declared properties only var applicableDataProperties = dataContract.ObjectProperties; if (_generatorOptions.UseOneOfForPolymorphism || _generatorOptions.UseAllOfForInheritance) { if (IsBaseTypeWithKnownSubTypes(dataContract.UnderlyingType, out IEnumerable <Type> subTypes)) { if (_generatorOptions.UseAllOfForInheritance) { // Ensure a schema for all known sub types is generated and added to the repository foreach (var subType in subTypes) { var subTypeContract = _serializerBehavior.GetDataContractForType(subType); GenerateReferencedSchema(subType, schemaRepository, () => GenerateObjectSchema(subTypeContract, schemaRepository)); } } if (_generatorOptions.UseOneOfForPolymorphism && TryGetDiscriminatorName(dataContract, out string discriminatorName)) { schema.Properties.Add(discriminatorName, new OpenApiSchema { Type = "string" }); schema.Required.Add(discriminatorName); } } if (IsKnownSubType(dataContract.UnderlyingType, out Type baseType)) { var baseTypeContract = _serializerBehavior.GetDataContractForType(baseType); if (_generatorOptions.UseAllOfForInheritance) { schema.AllOf = new List <OpenApiSchema> { GenerateReferencedSchema(baseType, schemaRepository, () => GenerateObjectSchema(baseTypeContract, schemaRepository)) }; // Reduce the set of properties to be defined in this schema to declared properties only applicableDataProperties = applicableDataProperties .Where(dataProperty => dataProperty.MemberInfo?.DeclaringType == dataContract.UnderlyingType); } if (_generatorOptions.UseOneOfForPolymorphism && !_generatorOptions.UseAllOfForInheritance && TryGetDiscriminatorName(baseTypeContract, out string discriminatorName)) { schema.Properties.Add(discriminatorName, new OpenApiSchema { Type = "string" }); schema.Required.Add(discriminatorName); } } } 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] = GeneratePropertySchema(dataProperty, 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); }
/// <summary> /// Visits <see cref="OpenApiSchema"/> /// </summary> public virtual void Visit(OpenApiSchema schema) { }
public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Null(Type type, OpenApiSchema expected) { var result = this._visitor.PayloadVisit(type, this._strategy); result.Should().Be(expected); }
/* * static void FixProperty (JsonSchema4 item , string name) * { * if (item.Properties.Keys.Contains(name)) * { * item.Properties.Remove(name); * * JsonProperty jsonProperty = new JsonProperty(); * jsonProperty.Type = JsonObjectType.String; * jsonProperty.IsNullableRaw = true; * KeyValuePair<string, JsonProperty> keyValuePair = new KeyValuePair<string, JsonProperty>(name, jsonProperty); * * item.Properties.Add(keyValuePair); * * } * } */ static void CheckProperties(OpenApiDocument swaggerDocument, List <string> itemsToKeep, OpenApiSchema item) { if (item.Reference != null) { string title = item.Reference.Id; if (title != null && !itemsToKeep.Contains(title)) { // recursive call. AddSubItems(swaggerDocument, itemsToKeep, title); } } else { if (item.Type != null && (item.Type == "object" || item.Type == "array") && item.Items?.Reference?.Id != null) { string title = item.Items.Reference.Id; if (title != null && !itemsToKeep.Contains(title)) { // recursive call. AddSubItems(swaggerDocument, itemsToKeep, title); } } } if (item.Properties != null) { foreach (var property in item.Properties) { if (property.Value.Reference != null) { string title = property.Value.Reference.Id; if (title != null && !itemsToKeep.Contains(title)) { // recursive call. AddSubItems(swaggerDocument, itemsToKeep, title); } } else { if ((property.Value.Type == "object" || property.Value.Type == "array") && property.Value.Items?.Reference?.Id != null) { string id = property.Value.Items.Reference.Id; if (id != null && !itemsToKeep.Contains(id)) { // recursive call. AddSubItems(swaggerDocument, itemsToKeep, id); } } } } } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Extensions.Add("X-foo", new OpenApiString("bar")); }
public Dictionary <string, OpenApiSchema> SchemaFromObject() { Dictionary <string, OpenApiSchema> Lista = new Dictionary <string, OpenApiSchema>(); foreach (Ac4yClass ac4yClass in Parameter.ClassList) { Dictionary <string, OpenApiSchema> PropertyLista = new Dictionary <string, OpenApiSchema>(); Dictionary <string, OpenApiSchema> PropertyListaWithoutID = new Dictionary <string, OpenApiSchema>(); foreach (Ac4yProperty property in ac4yClass.PropertyList) { if (property.Cardinality.Equals("COLLECTION")) { PropertyLista.Add(property.Name, new OpenApiSchema() { Type = "array", Items = new OpenApiSchema() { Type = "object", Title = property.TypeName }, Nullable = true, Description = property.Description }); } else if (property.NavigationProperty == true) { PropertyLista.Add(property.Name, new OpenApiSchema() { Type = "object", Description = property.Description, Title = property.Name, Nullable = true }); } else { PropertyLista.Add(property.Name, new OpenApiSchema() { Type = GetConvertedType(property.TypeName, TipusKonverziok), Format = GetConvertedType(property.TypeName, FormaKonverziok), Description = property.Description }); if (!property.Name.Equals("Id")) { PropertyListaWithoutID.Add(property.Name, new OpenApiSchema() { Type = GetConvertedType(property.TypeName, TipusKonverziok), Format = GetConvertedType(property.TypeName, FormaKonverziok), Description = property.Description }); } } } ; OpenApiSchema Schema = new OpenApiSchema() { Properties = PropertyLista }; OpenApiSchema SchemaWithoutID = new OpenApiSchema() { Properties = PropertyListaWithoutID }; Lista.Add(ac4yClass.Name, Schema); Lista.Add(ac4yClass.Name + "WithoutID", SchemaWithoutID); } return(Lista); }
private static object MapSchemaToObject(OpenApiSchema schema, string name = null) { if (schema == null) { return(null); } switch (schema.GetSchemaType()) { case SchemaType.Array: var jArray = new JArray(); for (int i = 0; i < ArrayItems; i++) { if (schema.Items.Properties.Count > 0) { var arrayItem = new JObject(); foreach (var property in schema.Items.Properties) { var objectValue = MapSchemaToObject(property.Value, property.Key); if (objectValue is JProperty jp) { arrayItem.Add(jp); } else { arrayItem.Add(new JProperty(property.Key, objectValue)); } } jArray.Add(arrayItem); } else { jArray.Add(MapSchemaToObject(schema.Items, name)); } } return(jArray); case SchemaType.Boolean: case SchemaType.Integer: case SchemaType.Number: case SchemaType.String: return(ExampleValueGenerator.GetExampleValue(schema)); case SchemaType.Object: var propertyAsJObject = new JObject(); foreach (var schemaProperty in schema.Properties) { string propertyName = schemaProperty.Key; var openApiSchema = schemaProperty.Value; if (openApiSchema.GetSchemaType() == SchemaType.Object) { var mapped = MapSchemaToObject(schemaProperty.Value, schemaProperty.Key); if (mapped is JProperty jp) { propertyAsJObject.Add(jp); } } else { bool propertyIsNullable = openApiSchema.Nullable || (openApiSchema.TryGetXNullable(out bool x) && x); propertyAsJObject.Add(new JProperty(propertyName, ExampleValueGenerator.GetExampleValue(openApiSchema))); } } return(name != null ? new JProperty(name, propertyAsJObject) : (JToken)propertyAsJObject); default: return(null); } }
public static Dictionary <string, OpenApiSchema> ToOpenApiSchemas(this Type type, NamingStrategy namingStrategy, OpenApiSchemaVisibilityAttribute attribute = null, bool returnSingleSchema = false, int depth = 0) { type.ThrowIfNullOrDefault(); var schema = (OpenApiSchema)null; var schemeName = type.GetOpenApiTypeName(namingStrategy); if (depth == 8) { schema = new OpenApiSchema() { Type = type.ToDataType(), Format = type.ToDataFormat() }; return(new Dictionary <string, OpenApiSchema>() { { schemeName, schema } }); } depth++; if (type.IsJObjectType()) { schema = typeof(object).ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value; return(new Dictionary <string, OpenApiSchema>() { { schemeName, schema } }); } if (type.IsOpenApiNullable(out var unwrappedValueType)) { schema = unwrappedValueType.ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value; schema.Nullable = true; return(new Dictionary <string, OpenApiSchema>() { { schemeName, schema } }); } schema = new OpenApiSchema() { Type = type.ToDataType(), Format = type.ToDataFormat() }; if (!attribute.IsNullOrDefault()) { var visibility = new OpenApiString(attribute.Visibility.ToDisplayName()); schema.Extensions.Add("x-ms-visibility", visibility); } if (type.IsUnflaggedEnumType()) { var converterAttribute = type.GetCustomAttribute <JsonConverterAttribute>(); if (!converterAttribute.IsNullOrDefault() && typeof(StringEnumConverter).IsAssignableFrom(converterAttribute.ConverterType)) { var enums = type.ToOpenApiStringCollection(namingStrategy); schema.Type = "string"; schema.Format = null; schema.Enum = enums; schema.Default = enums.First(); } else { var enums = type.ToOpenApiIntegerCollection(); schema.Enum = enums; schema.Default = enums.First(); } } if (type.IsSimpleType()) { return(new Dictionary <string, OpenApiSchema>() { { schemeName, schema } }); } if (type.IsOpenApiDictionary()) { schema.AdditionalProperties = type.GetGenericArguments()[1].ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value; return(new Dictionary <string, OpenApiSchema>() { { schemeName, schema } }); } if (type.IsOpenApiArray()) { schema.Type = "array"; schema.Items = (type.GetElementType() ?? type.GetGenericArguments()[0]).ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value; return(new Dictionary <string, OpenApiSchema>() { { schemeName, schema } }); } var allProperties = type.IsInterface ? new[] { type }.Concat(type.GetInterfaces()).SelectMany(i => i.GetProperties()) : type.GetProperties(); var properties = allProperties.Where(p => !p.ExistsCustomAttribute <JsonIgnoreAttribute>()); var retVal = new Dictionary <string, OpenApiSchema>(); foreach (var property in properties) { var visiblity = property.GetCustomAttribute <OpenApiSchemaVisibilityAttribute>(inherit: false); var propertyName = property.GetJsonPropertyName(namingStrategy); var ts = property.DeclaringType.GetGenericArguments(); if (!ts.Any()) { if (property.PropertyType.IsUnflaggedEnumType() && !returnSingleSchema) { var recur1 = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth); retVal.AddRange(recur1); var enumReference = new OpenApiReference() { Type = ReferenceType.Schema, Id = property.PropertyType.GetOpenApiReferenceId(false, false) }; var schema1 = new OpenApiSchema() { Reference = enumReference }; schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = schema1; } else if (property.PropertyType.IsSimpleType() || Nullable.GetUnderlyingType(property.PropertyType) != null || returnSingleSchema) { schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value; } else if (property.PropertyType.IsOpenApiDictionary()) { var elementType = property.PropertyType.GetGenericArguments()[1]; if (elementType.IsSimpleType() || elementType.IsOpenApiDictionary() || elementType.IsOpenApiArray()) { schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value; } else { var recur1 = elementType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth); retVal.AddRange(recur1); var elementReference = new OpenApiReference() { Type = ReferenceType.Schema, Id = elementType.GetOpenApiReferenceId(false, false) }; var dictionarySchema = new OpenApiSchema() { Type = "object", AdditionalProperties = new OpenApiSchema() { Reference = elementReference } }; schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = dictionarySchema; } } else if (property.PropertyType.IsOpenApiArray()) { var elementType = property.PropertyType.GetElementType() ?? property.PropertyType.GetGenericArguments()[0]; if (elementType.IsSimpleType() || elementType.IsOpenApiDictionary() || elementType.IsOpenApiArray()) { schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value; } else { var elementReference = elementType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth); retVal.AddRange(elementReference); var reference1 = new OpenApiReference() { Type = ReferenceType.Schema, Id = elementType.GetOpenApiReferenceId(false, false) }; var arraySchema = new OpenApiSchema() { Type = "array", Items = new OpenApiSchema() { Reference = reference1 } }; schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = arraySchema; } } else { var recur1 = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth); retVal.AddRange(recur1); var reference1 = new OpenApiReference() { Type = ReferenceType.Schema, Id = property.PropertyType.GetOpenApiReferenceId(false, false) }; var schema1 = new OpenApiSchema() { Reference = reference1 }; schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = schema1; } continue; } var reference = new OpenApiReference() { Type = ReferenceType.Schema, Id = property.PropertyType.GetOpenApiRootReferenceId() }; var referenceSchema = new OpenApiSchema() { Reference = reference }; if (!ts.Contains(property.PropertyType)) { if (property.PropertyType.IsOpenApiDictionary()) { reference.Id = property.PropertyType.GetOpenApiReferenceId(true, false); var dictionarySchema = new OpenApiSchema() { Type = "object", AdditionalProperties = referenceSchema }; schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = dictionarySchema; continue; } if (property.PropertyType.IsOpenApiArray()) { reference.Id = property.PropertyType.GetOpenApiReferenceId(false, true); var arraySchema = new OpenApiSchema() { Type = "array", Items = referenceSchema }; schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = arraySchema; continue; } schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value; continue; } schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = referenceSchema; } retVal[schemeName] = schema; return(retVal); }
public static string GetSchemaTitle(this OpenApiSchema schema) { return(schema.GetSchemaTitles().LastOrDefault()?.TrimStart('$'));// OData $ref }
public override void Parse(OpenApiObject data, IEndpointsParser parser) { base.Parse(data, parser); Schema = data.GetSchema("schema"); }