Exemplo n.º 1
0
        /// <summary>Generates the properties for the given type and schema.</summary>
        /// <param name="typeDescription">The type desription.</param>
        /// <param name="schema">The properties</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns></returns>
        protected override void GenerateObject(JsonSchema schema, JsonTypeDescription typeDescription, JsonSchemaResolver schemaResolver)
        {
            // iiQ Custom
            // .. Guards against "Item" is registered multiple times exception within base.GenerateObject
            if (typeDescription?.ContextualType?.Type?.FullName == "MongoDB.Bson.BsonValue" ||
                (typeDescription?.ContextualType?.Type?.FullName ?? "").StartsWith("System."))
            {
                return;
            }

            if (_isRootType)
            {
                _isRootType = false;
                base.GenerateObject(schema, typeDescription, schemaResolver);
                _isRootType = true;
            }
            else
            {
                if (!schemaResolver.HasSchema(typeDescription.ContextualType.OriginalType, false))
                {
                    _isRootType = true;
                    Generate(typeDescription.ContextualType.OriginalType, schemaResolver);
                    _isRootType = false;
                }

                schema.Reference = schemaResolver.GetSchema(typeDescription.ContextualType.OriginalType, false);
            }
        }
        private bool IsFileArray(Type type, JsonTypeDescription typeInfo)
        {
            var isFormFileCollection = type.Name == "IFormFileCollection";
            var isFileArray          = typeInfo.Type == JsonObjectType.Array && type.GenericTypeArguments.Any() &&
                                       _settings.ReflectionService.GetDescription(type.GenericTypeArguments[0], null, _settings).Type == JsonObjectType.File;

            return(isFormFileCollection || isFileArray);
        }
Exemplo n.º 3
0
        private OpenApiParameter TryAddFileParameter(
            OperationProcessorContext context, JsonTypeDescription typeInfo, ContextualParameterInfo contextualParameter)
        {
            var isFileArray             = IsFileArray(contextualParameter.Type, typeInfo);
            var hasSwaggerFileAttribute = contextualParameter.Attributes
                                          .FirstAssignableToTypeNameOrDefault("SwaggerFileAttribute", TypeNameStyle.Name) != null;

            if (typeInfo.Type == JsonObjectType.File ||
                typeInfo.Format == JsonFormatStrings.Binary ||
                hasSwaggerFileAttribute ||
                isFileArray)
            {
                return(AddFileParameter(context, contextualParameter, isFileArray));
            }

            return(null);
        }
        private async Task <SwaggerParameter> TryAddFileParameterAsync(
            OperationProcessorContext context, JsonTypeDescription info, ParameterInfo parameter)
        {
            var isFileArray = IsFileArray(parameter.ParameterType, info);

            var attributes = parameter.GetCustomAttributes()
                             .Union(parameter.ParameterType.GetTypeInfo().GetCustomAttributes());

            var hasSwaggerFileAttribute = attributes.Any(a =>
                                                         a.GetType().IsAssignableTo("SwaggerFileAttribute", TypeNameStyle.Name));

            if (info.Type == JsonObjectType.File || hasSwaggerFileAttribute || isFileArray)
            {
                return(await AddFileParameterAsync(context, parameter, isFileArray).ConfigureAwait(false));
            }

            return(null);
        }
Exemplo n.º 5
0
        /// <summary>Generates an enumeration in the given schema.</summary>
        /// <param name="schema">The schema.</param>
        /// <param name="typeDescription">The type description.</param>
        protected override void GenerateEnum(JsonSchema schema, JsonTypeDescription typeDescription)
        {
            var contextualType = typeDescription.ContextualType;

            schema.Type = typeDescription.Type;
            schema.Enumeration.Clear();
            schema.EnumerationNames.Clear();
            schema.IsFlagEnumerable = contextualType.GetTypeAttribute <FlagsAttribute>() != null;

            var underlyingType = Enum.GetUnderlyingType(contextualType.Type);

            foreach (var enumName in Enum.GetNames(contextualType.Type))
            {
                if (typeDescription.Type == JsonObjectType.Integer)
                {
                    var value = Convert.ChangeType(Enum.Parse(contextualType.Type, enumName), underlyingType);
                    schema.Enumeration.Add(value);
                }
                else
                {
                    // EnumMember only checked if StringEnumConverter is used
                    var attributes          = contextualType.TypeInfo.GetDeclaredField(enumName).GetCustomAttributes(typeof(EnumMemberAttribute));
                    var enumMemberAttribute = (EnumMemberAttribute)attributes.FirstOrDefault();
                    if (enumMemberAttribute != null && !string.IsNullOrEmpty(enumMemberAttribute.Value))
                    {
                        schema.Enumeration.Add(enumMemberAttribute.Value);
                    }
                    else
                    {
                        schema.Enumeration.Add(enumName);
                    }
                }

                schema.EnumerationNames.Add(enumName);
            }

            if (typeDescription.Type == JsonObjectType.Integer && this.Settings.GenerateEnumMappingDescription)
            {
                schema.Description = (schema.Description + "\n\n" +
                                      string.Join("\n", schema.Enumeration.Select((e, i) => e + " = " + schema.EnumerationNames[i]))).Trim();
            }
        }
Exemplo n.º 6
0
        private bool IsFileArray(Type type, JsonTypeDescription typeInfo)
        {
            var isFormFileCollection = type.Name == "IFormFileCollection";

            if (isFormFileCollection)
            {
                return(true);
            }

            if (typeInfo.Type == JsonObjectType.Array && type.GenericTypeArguments.Any())
            {
                var description = _settings.ReflectionService.GetDescription(type.GenericTypeArguments[0].ToContextualType(), _settings);
                if (description.Type == JsonObjectType.File || description.Format == JsonFormatStrings.Binary)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 7
0
        /// <summary>Generates the properties for the given type and schema.</summary>
        /// <param name="typeDescription">The type desription.</param>
        /// <param name="schema">The properties</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns></returns>
        protected override void GenerateObject(JsonSchema schema, JsonTypeDescription typeDescription, JsonSchemaResolver schemaResolver)
        {
            if (_isRootType)
            {
                _isRootType = false;
                base.GenerateObject(schema, typeDescription, schemaResolver);
                _isRootType = true;
            }
            else
            {
                if (!schemaResolver.HasSchema(typeDescription.ContextualType.OriginalType, false))
                {
                    _isRootType = true;
                    Generate(typeDescription.ContextualType.OriginalType, schemaResolver);
                    _isRootType = false;
                }

                schema.Reference = schemaResolver.GetSchema(typeDescription.ContextualType.OriginalType, false);
            }
        }
Exemplo n.º 8
0
        /// <summary>Generates the properties for the given type and schema.</summary>
        /// <param name="type">The types.</param>
        /// <param name="typeDescription">The type desription.</param>
        /// <param name="schema">The properties</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns></returns>
        protected override async Task GenerateObjectAsync(Type type, JsonTypeDescription typeDescription, JsonSchema4 schema, JsonSchemaResolver schemaResolver)
        {
            if (_isRootType)
            {
                _isRootType = false;
                await base.GenerateObjectAsync(type, typeDescription, schema, schemaResolver);

                _isRootType = true;
            }
            else
            {
                if (!schemaResolver.HasSchema(type, false))
                {
                    _isRootType = true;
                    await GenerateAsync(type, schemaResolver);

                    _isRootType = false;
                }

                schema.Reference = schemaResolver.GetSchema(type, false);
            }
        }
Exemplo n.º 9
0
        private OpenApiParameter CreatePrimitiveSwaggerParameter(ContextualType contextualParameter, JsonTypeDescription typeDescription)
        {
            OpenApiParameter operationParameter;

            if (typeDescription.RequiresSchemaReference(_settings.TypeMappers))
            {
                var referencedSchema = _settings.SchemaGenerator.Generate(contextualParameter, _schemaResolver);

                operationParameter = new OpenApiParameter
                {
                    Type         = typeDescription.Type,
                    CustomSchema = new JsonSchema {
                        Reference = referencedSchema.ActualSchema
                    }
                };

                // Copy enumeration for compatibility with other tools which do not understand x-schema.
                // The enumeration will be ignored by NSwag and only the x-schema is processed
                if (referencedSchema.ActualSchema.IsEnumeration)
                {
                    operationParameter.Enumeration.Clear();
                    foreach (var item in referencedSchema.ActualSchema.Enumeration)
                    {
                        operationParameter.Enumeration.Add(item);
                    }
                }

                _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter, typeDescription);
            }
            else
            {
                operationParameter = _settings.SchemaGenerator.Generate <OpenApiParameter>(contextualParameter, _schemaResolver);
                _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter, typeDescription);
            }

            return(operationParameter);
        }
Exemplo n.º 10
0
        private OpenApiParameter CreatePrimitiveOpenApiParameter(ContextualType contextualParameter, JsonTypeDescription typeDescription)
        {
            OpenApiParameter operationParameter;

            if (typeDescription.RequiresSchemaReference(_settings.TypeMappers))
            {
                operationParameter        = new OpenApiParameter();
                operationParameter.Schema = new JsonSchema();

                _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter.Schema, typeDescription);

                var referencedSchema = _settings.SchemaGenerator.Generate(contextualParameter, _schemaResolver);

                var hasSchemaAnnotations = JsonConvert.SerializeObject(operationParameter.Schema) != "{}";
                if (hasSchemaAnnotations || typeDescription.IsNullable)
                {
                    operationParameter.Schema.IsNullableRaw = true;
                    operationParameter.Schema.OneOf.Add(new JsonSchema {
                        Reference = referencedSchema.ActualSchema
                    });
                }
                else
                {
                    operationParameter.Schema = new JsonSchema {
                        Reference = referencedSchema.ActualSchema
                    };
                }
            }
            else
            {
                operationParameter        = new OpenApiParameter();
                operationParameter.Schema = _settings.SchemaGenerator.GenerateWithReferenceAndNullability <JsonSchema>(
                    contextualParameter, typeDescription.IsNullable, _schemaResolver);

                _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter.Schema, typeDescription);
            }

            return(operationParameter);
        }
Exemplo n.º 11
0
        private OpenApiParameter AddPrimitiveParametersFromUri(
            OperationProcessorContext context, string httpPath, string name, ContextualParameterInfo contextualParameter, JsonTypeDescription typeDescription)
        {
            var operation = context.OperationDescription.Operation;

            if (typeDescription.Type.HasFlag(JsonObjectType.Array))
            {
                var parameterDocumentation = contextualParameter.GetDescription(_settings);
                var operationParameter     = context.DocumentGenerator.CreatePrimitiveParameter(
                    name, parameterDocumentation, contextualParameter);

                operationParameter.Kind = OpenApiParameterKind.Query;
                operation.Parameters.Add(operationParameter);
                return(operationParameter);
            }
            else
            {
                foreach (var contextualProperty in contextualParameter.Type.GetContextualProperties())
                {
                    if (contextualProperty.ContextAttributes.Select(a => a.GetType()).All(a =>
                                                                                          !a.IsAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name) &&
                                                                                          !a.IsAssignableToTypeName("JsonIgnoreAttribute", TypeNameStyle.Name)))
                    {
                        var fromQueryAttribute = contextualProperty.ContextAttributes.SingleOrDefault(a => a.GetType().Name == "FromQueryAttribute");
                        var propertyName       = fromQueryAttribute.TryGetPropertyValue <string>("Name") ??
                                                 context.SchemaGenerator.GetPropertyName(null, contextualProperty);

                        dynamic fromRouteAttribute = contextualProperty.ContextAttributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromRouteAttribute");
                        if (fromRouteAttribute != null && !string.IsNullOrEmpty(fromRouteAttribute?.Name))
                        {
                            propertyName = fromRouteAttribute?.Name;
                        }

                        dynamic fromHeaderAttribute = contextualProperty.ContextAttributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromHeaderAttribute");
                        if (fromHeaderAttribute != null && !string.IsNullOrEmpty(fromHeaderAttribute?.Name))
                        {
                            propertyName = fromHeaderAttribute?.Name;
                        }

                        var propertySummary    = contextualProperty.PropertyInfo.GetXmlDocsSummary(_settings.ResolveExternalXmlDocumentation);
                        var operationParameter = context.DocumentGenerator.CreatePrimitiveParameter(propertyName, propertySummary, contextualProperty.AccessorType);

                        // TODO: Check if required can be controlled with mechanisms other than RequiredAttribute

                        var parameterInfo = _settings.ReflectionService.GetDescription(contextualProperty.AccessorType, _settings);
                        var isFileArray   = IsFileArray(contextualProperty.AccessorType.Type, parameterInfo);

                        if (parameterInfo.Type == JsonObjectType.File || isFileArray)
                        {
                            InitializeFileParameter(operationParameter, isFileArray);
                        }
                        else if (fromRouteAttribute != null ||
                                 httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + "}") ||
                                 httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + ":"))
                        {
                            operationParameter.Kind          = OpenApiParameterKind.Path;
                            operationParameter.IsNullableRaw = false;
                            operationParameter.IsRequired    = true; // Path is always required => property not needed
                        }
                        else if (fromHeaderAttribute != null)
                        {
                            operationParameter.Kind = OpenApiParameterKind.Header;
                        }
                        else
                        {
                            operationParameter.Kind = OpenApiParameterKind.Query;
                        }

                        operation.Parameters.Add(operationParameter);
                    }
                }

                return(null);
            }
        }
Exemplo n.º 12
0
        private async Task AddPrimitiveParametersFromUriAsync(OperationProcessorContext context, string httpPath, string name, ParameterInfo parameter, JsonTypeDescription typeDescription)
        {
            var operation = context.OperationDescription.Operation;

            if (typeDescription.Type.HasFlag(JsonObjectType.Array))
            {
                var attributes = parameter.GetCustomAttributes();

                var parameterDocumentation = await parameter.GetDescriptionAsync(attributes).ConfigureAwait(false);

                var operationParameter = await context.SwaggerGenerator.CreatePrimitiveParameterAsync(
                    name, parameterDocumentation, parameter.ParameterType, attributes).ConfigureAwait(false);

                operationParameter.Kind = SwaggerParameterKind.Query;
                operation.Parameters.Add(operationParameter);
            }
            else
            {
                foreach (var property in parameter.ParameterType.GetRuntimeProperties())
                {
                    var attributes = property.GetCustomAttributes().ToList();
                    if (attributes.All(a => a.GetType().Name != "SwaggerIgnoreAttribute" && a.GetType().Name != "JsonIgnoreAttribute"))
                    {
                        var fromQueryAttribute = attributes.SingleOrDefault(a => a.GetType().Name == "FromQueryAttribute");
                        var propertyName       = fromQueryAttribute.TryGetPropertyValue <string>("Name") ??
                                                 context.SchemaGenerator.GetPropertyName(null, property);

                        dynamic fromRouteAttribute = attributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromRouteAttribute");
                        if (fromRouteAttribute != null && !string.IsNullOrEmpty(fromRouteAttribute?.Name))
                        {
                            propertyName = fromRouteAttribute?.Name;
                        }

                        dynamic fromHeaderAttribute = attributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromHeaderAttribute");
                        if (fromHeaderAttribute != null && !string.IsNullOrEmpty(fromHeaderAttribute?.Name))
                        {
                            propertyName = fromHeaderAttribute?.Name;
                        }

                        var propertySummary = await property.GetXmlSummaryAsync().ConfigureAwait(false);

                        var operationParameter = await context.SwaggerGenerator.CreatePrimitiveParameterAsync(
                            propertyName, propertySummary, property.PropertyType, attributes).ConfigureAwait(false);

                        // TODO: Check if required can be controlled with mechanisms other than RequiredAttribute

                        var parameterInfo = _settings.ReflectionService.GetDescription(property.PropertyType, attributes, _settings);
                        var isFileArray   = IsFileArray(property.PropertyType, parameterInfo);
                        if (parameterInfo.Type == JsonObjectType.File || isFileArray)
                        {
                            InitializeFileParameter(operationParameter, isFileArray);
                        }
                        else if (fromRouteAttribute != null ||
                                 httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + "}") ||
                                 httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + ":"))
                        {
                            operationParameter.Kind          = SwaggerParameterKind.Path;
                            operationParameter.IsNullableRaw = false;
                            operationParameter.IsRequired    = true; // Path is always required => property not needed
                        }
                        else if (fromHeaderAttribute != null)
                        {
                            operationParameter.Kind = SwaggerParameterKind.Header;
                        }
                        else
                        {
                            operationParameter.Kind = SwaggerParameterKind.Query;
                        }

                        operation.Parameters.Add(operationParameter);
                    }
                }
            }
        }