private OpenApiSchema GeneratePrimitiveSchema(DataContract dataContract) { var schema = new OpenApiSchema { Type = dataContract.DataType.ToString().ToLower(CultureInfo.InvariantCulture), Format = dataContract.Format }; if (dataContract.EnumValues != null) { schema.Enum = dataContract.EnumValues .Distinct() .Select(value => OpenApiAnyFactory.CreateFor(schema, value)) .ToList(); } return(schema); }
/// <summary> /// Applies the filter to the specified operation using the given context. /// </summary> /// <param name="operation">The operation to apply the filter to.</param> /// <param name="context">The current operation filter context.</param> public void Apply(OpenApiOperation operation, OperationFilterContext context) { var apiDescription = context.ApiDescription; //operation.Deprecated |= apiDescription.IsDeprecated(); foreach (var responseType in context.ApiDescription.SupportedResponseTypes) { var responseKey = responseType.IsDefaultResponse ? "default" : responseType.StatusCode.ToString(); var response = operation.Responses[responseKey]; foreach (var contentType in response.Content.Keys) { if (!responseType.ApiResponseFormats.Any(x => x.MediaType == contentType)) { response.Content.Remove(contentType); } } } if (operation.Parameters == null) { return; } foreach (var parameter in operation.Parameters) { var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); if (parameter.Description == null) { parameter.Description = description.ModelMetadata?.Description; } if (parameter.Schema.Default == null && description.DefaultValue != null) { var json = JsonSerializer.Serialize(description.DefaultValue, description.ModelMetadata.ModelType); parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json); } parameter.Required |= description.IsRequired; } }
/// <summary> /// Applies the filter to the specified operation using the given context. /// </summary> /// <param name="operation">The operation to apply the filter to.</param> /// <param name="context">The current operation filter context.</param> public void Apply(OpenApiOperation operation, OperationFilterContext context) { var apiDescription = context.ApiDescription; operation.Deprecated |= apiDescription.IsDeprecated(); foreach (var responseType in context.ApiDescription.SupportedResponseTypes) { // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/b7cf75e7905050305b115dd96640ddd6e74c7ac9/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs#L383-L387 var responseKey = responseType.IsDefaultResponse ? "default" : responseType.StatusCode.ToString(); var response = operation.Responses[responseKey]; foreach (var contentType in response.Content.Keys) { if (responseType.ApiResponseFormats.All(x => x.MediaType != contentType)) { response.Content.Remove(contentType); } } } if (operation.Parameters == null) { return; } foreach (var parameter in operation.Parameters) { var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); parameter.Description ??= description.ModelMetadata.Description; if (parameter.Schema.Default == null && description.DefaultValue != null) { // REF: https://github.com/Microsoft/aspnet-api-versioning/issues/429#issuecomment-605402330 var json = JsonSerializer.Serialize(description.DefaultValue, description.ModelMetadata.ModelType); parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json); } parameter.Required |= description.IsRequired; } }
private void ApplyParameterMetadata(OpenApiSchema schema, Type type, ParameterInfo parameterInfo) { if (schema.Reference != null && _generatorOptions.UseAllOfToExtendReferenceSchemas) { schema.AllOf = new[] { new OpenApiSchema { Reference = schema.Reference } }; schema.Reference = null; } if (schema.Reference == null) { schema.Nullable = type.IsReferenceOrNullableType(); schema.ApplyCustomAttributes(parameterInfo.GetCustomAttributes()); if (parameterInfo.HasDefaultValue) { schema.Default = OpenApiAnyFactory.CreateFor(schema, parameterInfo.DefaultValue); } } }
public void CreateFromJson_Array(string json, Type expectedType, params object[] expectedValues) { var openApiAnyObject = OpenApiAnyFactory.CreateFromJson(json); Assert.NotNull(openApiAnyObject); Assert.Equal(typeof(OpenApiArray), openApiAnyObject.GetType()); Assert.Equal(AnyType.Array, openApiAnyObject.AnyType); var array = (OpenApiArray)openApiAnyObject; for (var i = 0; i < array.Count; i++) { Assert.NotNull(array[i]); Assert.Equal(expectedType, array[i].GetType()); if (expectedValues.Length > 0) { var valueProperty = expectedType.GetProperty("Value"); var expectedValue = expectedValues[i]; var actualValue = valueProperty.GetValue(array[i]); Assert.Equal(expectedValue, actualValue); } } }
public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (operation.Parameters == null) { operation.Parameters = new List <OpenApiParameter>(); } var schema = new OpenApiSchema { Type = "String" }; operation.Parameters.Add(new OpenApiParameter { Name = "X-Tenant-Id", Description = "Tenant id for the request", In = ParameterLocation.Header, Required = false, Example = OpenApiAnyFactory.CreateFor(schema, "first-tenant"), Schema = schema }); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema.Properties == null || schema.Properties.Count == 0) { return; } //if (context.ApiModel == null || context.ApiModel.Type == null) // return; var propertyInfos = context.Type.GetProperties(); foreach (PropertyInfo propertyInfo in propertyInfos) { var attribute = propertyInfo.GetCustomAttribute <ExampleAttribute>(); if (attribute != null) { foreach (KeyValuePair <string, OpenApiSchema> property in schema.Properties) { if (ToCamelCase(propertyInfo.Name) == property.Key) { if (attribute.Value == null) { property.Value.Example = new OpenApiNull(); break; } var ss = OpenApiAnyFactory.CreateFor(property.Value, attribute.Value); property.Value.Example = OpenApiAnyFactory.CreateFor(property.Value, attribute.Value); //property.Value.Example = OpenApiAnyFactory.TryCreateFor(property.Value, attribute.Value, out IOpenApiAny openApiAny) // ? openApiAny // : null; } } } } }
public override OpenApiSchema CreateDefinitionSchema(Type type, SchemaRepository schemaRepository) { var jsonContract = _contractResolver.ResolveContract(type); var stringEnumConverter = (jsonContract.Converter as StringEnumConverter) ?? _serializerSettings.Converters.OfType <StringEnumConverter>().FirstOrDefault(); // Temporary shim to support obsolete config options if (stringEnumConverter == null && _generatorOptions.DescribeAllEnumsAsStrings) { stringEnumConverter = new StringEnumConverter(_generatorOptions.DescribeStringEnumsInCamelCase); } var schema = (stringEnumConverter != null) ? EnumTypeMap[typeof(string)]() : EnumTypeMap[type.GetEnumUnderlyingType()](); if (stringEnumConverter != null) { schema.Enum = type.GetMembers(BindingFlags.Public | BindingFlags.Static) .Select(member => { var memberAttribute = member.GetCustomAttributes <EnumMemberAttribute>().FirstOrDefault(); var stringValue = GetConvertedEnumName(stringEnumConverter, (memberAttribute?.Value ?? member.Name), (memberAttribute?.Value != null)); return(OpenApiAnyFactory.CreateFor(schema, stringValue)); }) .ToList(); } else { schema.Enum = type.GetEnumValues() .Cast <object>() .Select(value => OpenApiAnyFactory.CreateFor(schema, value)) .ToList(); } return(schema); }
private void ApplyParamTags(OpenApiParameter parameter, ParameterFilterContext context) { if (!(context.ParameterInfo.Member is MethodInfo methodInfo)) { return; } // If method is from a constructed generic type, look for comments from the generic type method var targetMethod = methodInfo.DeclaringType.IsConstructedGenericType ? methodInfo.GetUnderlyingGenericTypeMethod() : methodInfo; if (targetMethod == null) { return; } var methodMemberName = XmlCommentsNodeNameHelper.GetMemberNameForMethod(targetMethod); var paramNode = _xmlNavigator.SelectSingleNode( $"/doc/members/member[@name='{methodMemberName}']/param[@name='{context.ParameterInfo.Name}']"); if (paramNode != null) { parameter.Description = XmlCommentsTextHelper.Humanize(paramNode.InnerXml); var example = paramNode.GetAttribute("example", ""); if (!string.IsNullOrEmpty(example)) { var exampleAsJson = (parameter.Schema?.ResolveType(context.SchemaRepository) == "string") ? $"\"{example}\"" : example; parameter.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson); } } }
/// <summary> /// Applies the filter to the specified operation using the given context. /// </summary> /// <param name="operation">The operation to apply the filter to.</param> /// <param name="context">The current operation filter context.</param> public void Apply(OpenApiOperation operation, OperationFilterContext context) { var apiDescription = context.ApiDescription; var apiVersion = apiDescription.GetApiVersion(); var model = apiDescription.ActionDescriptor.GetApiVersionModel(ApiVersionMapping.Explicit | ApiVersionMapping.Implicit); operation.Deprecated = model.DeprecatedApiVersions.Contains(apiVersion); if (operation.Parameters == null) { return; } // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412 // REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413 foreach (var parameter in operation.Parameters) { var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); if (parameter.Description == null) { parameter.Description = description.ModelMetadata?.Description; } if (parameter.Schema.Default == null && description.DefaultValue != null) { // REF: https://github.com/Microsoft/aspnet-api-versioning/issues/429#issuecomment-605402330 var json = JsonSerializer.Serialize(description.DefaultValue, description.ModelMetadata.ModelType); parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json); } parameter.Required |= description.IsRequired; } }
/// <summary> /// 实现过滤器方法 /// </summary> /// <param name="model"></param> /// <param name="context"></param> public void Apply(OpenApiSchema model, SchemaFilterContext context) { var type = context.Type; // 排除其他程序集的枚举 if (type.IsEnum && App.Assemblies.Contains(type.Assembly)) { model.Enum.Clear(); var stringBuilder = new StringBuilder(); stringBuilder.Append($"{model.Description}<br />"); var enumValues = Enum.GetValues(type); foreach (var value in enumValues) { // 获取枚举成员特性 var fieldinfo = type.GetField(Enum.GetName(type, value)); var descriptionAttribute = fieldinfo.GetCustomAttribute <DescriptionAttribute>(true); model.Enum.Add(OpenApiAnyFactory.CreateFromJson(JSON.Serialize(value))); stringBuilder.Append($" {descriptionAttribute?.Description} {value} = {value}<br />"); } model.Description = stringBuilder.ToString(); } }
public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (operation.Parameters == null) { operation.Parameters = new List <OpenApiParameter>(); } operation.Parameters.Add(new OpenApiParameter { Name = "Accept-Language", In = ParameterLocation.Header, Description = "Supported languages", Schema = new OpenApiSchema { Default = new OpenApiString("en"), Type = "string", Enum = Localization.SupportedCultures .Select(c => OpenApiAnyFactory.CreateFor(new OpenApiSchema { Type = "string" }, c)).ToList() }, Required = false }); }
public void CreateFromJson_Object() { var json = JsonSerializer.Serialize(new { int_value = 1, long_value = 4294877294L, float_value = 1.5f, double_value = 1.5e308, string_value = "abc", true_value = true, false_value = false, array_value = new[] { 1, 2 }, object_value = new { a = 1, b = 2 } }); var openApiAnyObject = OpenApiAnyFactory.CreateFromJson(json); Assert.NotNull(openApiAnyObject); Assert.Equal(typeof(OpenApiObject), openApiAnyObject.GetType()); Assert.Equal(AnyType.Object, openApiAnyObject.AnyType); var obj = (OpenApiObject)openApiAnyObject; Assert.NotNull(obj["int_value"]); Assert.Equal(typeof(OpenApiInteger), obj["int_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["int_value"].AnyType); Assert.Equal(1, ((OpenApiInteger)obj["int_value"]).Value); Assert.NotNull(obj["long_value"]); Assert.Equal(typeof(OpenApiLong), obj["long_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["long_value"].AnyType); Assert.Equal(4294877294L, ((OpenApiLong)obj["long_value"]).Value); Assert.NotNull(obj["float_value"]); Assert.Equal(typeof(OpenApiFloat), obj["float_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["float_value"].AnyType); Assert.Equal(1.5f, ((OpenApiFloat)obj["float_value"]).Value); Assert.NotNull(obj["double_value"]); Assert.Equal(typeof(OpenApiDouble), obj["double_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["double_value"].AnyType); Assert.Equal(1.5e308, ((OpenApiDouble)obj["double_value"]).Value); Assert.NotNull(obj["string_value"]); Assert.Equal(typeof(OpenApiString), obj["string_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["string_value"].AnyType); Assert.Equal("abc", ((OpenApiString)obj["string_value"]).Value); Assert.NotNull(obj["true_value"]); Assert.Equal(typeof(OpenApiBoolean), obj["true_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["true_value"].AnyType); Assert.True(((OpenApiBoolean)obj["true_value"]).Value); Assert.NotNull(obj["false_value"]); Assert.Equal(typeof(OpenApiBoolean), obj["false_value"].GetType()); Assert.Equal(AnyType.Primitive, obj["false_value"].AnyType); Assert.False(((OpenApiBoolean)obj["false_value"]).Value); Assert.NotNull(obj["array_value"]); Assert.Equal(typeof(OpenApiArray), obj["array_value"].GetType()); Assert.Equal(AnyType.Array, obj["array_value"].AnyType); Assert.NotNull(obj["object_value"]); Assert.Equal(typeof(OpenApiObject), obj["object_value"].GetType()); Assert.Equal(AnyType.Object, obj["object_value"].AnyType); }
private OpenApiSchema GenerateSchemaForMember( Type modelType, SchemaRepository schemaRepository, MemberInfo memberInfo, ParameterInfo parameterInfo, DataProperty dataProperty = null) { var dataContract = GetDataContractFor(modelType); var schema = _generatorOptions.UseOneOfForPolymorphism && IsBaseTypeWithKnownTypesDefined(dataContract, parameterInfo, out var knownTypesDataContracts) ? GeneratePolymorphicSchema(dataContract, schemaRepository, knownTypesDataContracts, parameterInfo) : GenerateConcreteSchema(dataContract, schemaRepository, parameterInfo); if (_generatorOptions.UseAllOfToExtendReferenceSchemas && schema.Reference != null) { schema.AllOf = new[] { new OpenApiSchema { Reference = schema.Reference } }; schema.Reference = null; } if (schema.Reference == null) { var customAttributes = memberInfo.GetInlineAndMetadataAttributes(); // Nullable, ReadOnly & WriteOnly are only relevant for Schema "properties" (i.e. where dataProperty is non-null) if (dataProperty != null) { schema.Nullable = _generatorOptions.SupportNonNullableReferenceTypes ? dataProperty.IsNullable && !customAttributes.OfType <RequiredAttribute>().Any() && !memberInfo.IsNonNullableReferenceType() : dataProperty.IsNullable && !customAttributes.OfType <RequiredAttribute>().Any(); schema.ReadOnly = dataProperty.IsReadOnly; schema.WriteOnly = dataProperty.IsWriteOnly; } var defaultValueAttribute = customAttributes.OfType <DefaultValueAttribute>().FirstOrDefault(); if (defaultValueAttribute != null) { var defaultAsJson = dataContract.JsonConverter(defaultValueAttribute.Value); schema.Default = OpenApiAnyFactory.CreateFromJson(defaultAsJson); } var obsoleteAttribute = customAttributes.OfType <ObsoleteAttribute>().FirstOrDefault(); if (obsoleteAttribute != null) { schema.Deprecated = true; } // NullableAttribute behaves diffrently for Dictionaries if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { schema.AdditionalProperties.Nullable = !memberInfo.IsDictionaryValueNonNullable(); } schema.ApplyValidationAttributes(customAttributes); ApplyFilters(schema, modelType, schemaRepository, memberInfo: memberInfo); } return(schema); }