Exemple #1
0
        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;
            }
        }
Exemple #4
0
        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);
                }
            }
        }
Exemple #6
0
        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
            });
        }
Exemple #7
0
        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);
        }
Exemple #9
0
        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($"&nbsp;{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);
        }