Example #1
0
        private TSchemaType CreateAndAddSchema <TSchemaType>(SwaggerService service, Type type, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            if (type.Name == "Task`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (type.Name == "JsonResult`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (type.Name == "IHttpActionResult" || type.Name == "HttpResponseMessage" || type.InheritsFrom("HttpResponseMessage"))
            {
                type = typeof(object);
            }

            var info = JsonObjectTypeDescription.FromType(type);

            if (info.Type.HasFlag(JsonObjectType.Object))
            {
                if (type == typeof(object))
                {
                    return(new TSchemaType
                    {
                        Type = JsonObjectType.Object,
                        AllowAdditionalProperties = false
                    });
                }

                if (!schemaResolver.HasSchema(type, false))
                {
                    var schemaGenerator = new RootTypeJsonSchemaGenerator(service, Settings);
                    schemaGenerator.Generate <JsonSchema4>(type, schemaResolver);
                }

                return(new TSchemaType
                {
                    Type = JsonObjectType.Object,
                    SchemaReference = schemaResolver.GetSchema(type, false)
                });
            }

            if (info.Type.HasFlag(JsonObjectType.Array))
            {
                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                return(new TSchemaType
                {
                    Type = JsonObjectType.Array,
                    Item = CreateAndAddSchema <JsonSchema4>(service, itemType, schemaResolver)
                });
            }

            var generator = new RootTypeJsonSchemaGenerator(service, Settings);

            return(generator.Generate <TSchemaType>(type, schemaResolver));
        }
Example #2
0
        /// <summary></summary>
        /// <typeparam name="TSchemaType"></typeparam>
        /// <param name="schemaGenerator"></param>
        /// <param name="schemaResolver"></param>
        /// <returns></returns>
        public virtual TSchemaType GetSchema <TSchemaType>(JsonSchemaGenerator schemaGenerator, ISchemaResolver schemaResolver) where TSchemaType : JsonSchema4, new()
        {
            if (!schemaResolver.HasSchema(MappedType, false))
            {
                schemaResolver.AddSchema(MappedType, false, _schema);
            }

            return(null);
        }
Example #3
0
        /// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary>
        /// <typeparam name="TSchemaType">The type of the schema type.</typeparam>
        /// <param name="type">The type.</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns>The schema.</returns>
        /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception>
        /// <exception cref="InvalidOperationException">Could not find item type of enumeration type.</exception>
        public TSchemaType Generate <TSchemaType>(Type type, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            var schema = new TSchemaType();

            var typeDescription = JsonObjectTypeDescription.FromType(type);

            schema.Type   = typeDescription.Type;
            schema.Format = typeDescription.Format;

            if (schema.Type.HasFlag(JsonObjectType.Object))
            {
                if (typeDescription.IsDictionary)
                {
                    GenerateDictionary(type, schema, schemaResolver);
                }
                else
                {
                    if (type == typeof(object))
                    {
                        return(new TSchemaType
                        {
                            Type = JsonObjectType.Object,
                            AllowAdditionalProperties = false
                        });
                    }

                    schema.TypeName = GetTypeName(type);

                    if (schemaResolver.HasSchema(type))
                    {
                        schema.SchemaReference = schemaResolver.GetSchema(type);
                        return(schema);
                    }

                    GenerateObject(type, schema, schemaResolver);
                    GenerateInheritance(type, schema, schemaResolver);
                }
            }
            else if (schema.Type.HasFlag(JsonObjectType.Array))
            {
                schema.Type = JsonObjectType.Array;

                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                if (itemType == null)
                {
                    throw new InvalidOperationException("Could not find item type of enumeration type '" + type.FullName + "'.");
                }

                schema.Item = Generate <JsonSchema4>(itemType, schemaResolver);
            }

            TryLoadEnumerations(type, schema);

            return(schema);
        }
Example #4
0
        private TSchemaType CreateAndAddSchema <TSchemaType>(Type type, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            if (type.Name == "Task`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (type.Name == "JsonResult`1")
            {
                type = type.GenericTypeArguments[0];
            }

            var info = JsonObjectTypeDescription.FromType(type);

            if (info.Type.HasFlag(JsonObjectType.Object))
            {
                if (!schemaResolver.HasSchema(type))
                {
                    var schemaGenerator = new RootTypeJsonSchemaGenerator(_service);
                    schemaGenerator.Generate <JsonSchema4>(type, schemaResolver);
                }

                //load
                //目前先屏蔽处理某些特定类型的异常
                //Dictionary<string,string>
                JsonSchema4 t = null;
                try
                {
                    t = schemaResolver.GetSchema(type);
                }
                catch (Exception)
                {
                }
                return(new TSchemaType
                {
                    Type = JsonObjectType.Object,
                    SchemaReference = t
                });
            }

            if (info.Type.HasFlag(JsonObjectType.Array))
            {
                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                return(new TSchemaType
                {
                    Type = JsonObjectType.Array,
                    Item = CreateAndAddSchema <JsonSchema4>(itemType, schemaResolver)
                });
            }

            var generator = new RootTypeJsonSchemaGenerator(_service);

            return(generator.Generate <TSchemaType>(type, schemaResolver));
        }
Example #5
0
        private void GenerateKnownTypes(Type type, ISchemaResolver schemaResolver, ISchemaDefinitionAppender schemaDefinitionAppender)
        {
            foreach (dynamic knownTypeAttribute in type.GetTypeInfo().GetCustomAttributes().Where(a => a.GetType().Name == "KnownTypeAttribute"))
            {
                var typeDescription = JsonObjectTypeDescription.FromType(knownTypeAttribute.Type, null, Settings.DefaultEnumHandling);
                var isIntegerEnum   = typeDescription.Type == JsonObjectType.Integer;

                if (!schemaResolver.HasSchema(knownTypeAttribute.Type, isIntegerEnum))
                {
                    var knownSchema = Generate(knownTypeAttribute.Type, schemaResolver, schemaDefinitionAppender);
                    schemaDefinitionAppender.Append(knownSchema.ActualSchema);
                }
            }
        }
Example #6
0
        private void GenerateKnownTypes(Type type, JsonSchema4 rootSchema, ISchemaDefinitionAppender schemaDefinitionAppender, ISchemaResolver schemaResolver)
        {
            foreach (var knownTypeAttribute in type.GetTypeInfo().GetCustomAttributes <KnownTypeAttribute>())
            {
                var typeDescription = JsonObjectTypeDescription.FromType(knownTypeAttribute.Type, null, Settings.DefaultEnumHandling);
                var isIntegerEnum   = typeDescription.Type == JsonObjectType.Integer;

                if (!schemaResolver.HasSchema(knownTypeAttribute.Type, isIntegerEnum))
                {
                    var knownSchema = Generate(knownTypeAttribute.Type, rootSchema, null, schemaDefinitionAppender, schemaResolver);
                    schemaDefinitionAppender.Append(rootSchema, knownSchema.ActualSchema);
                }
            }
        }
        /// <summary>Generates the properties for the given type and schema.</summary>
        /// <typeparam name="TSchemaType">The type of the schema type.</typeparam>
        /// <param name="type">The types.</param>
        /// <param name="schema">The properties</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        protected override void GenerateObject <TSchemaType>(Type type, TSchemaType schema, ISchemaResolver schemaResolver)
        {
            if (_isRootType)
            {
                _isRootType = false;
                base.GenerateObject(type, schema, schemaResolver);
            }
            else
            {
                if (!schemaResolver.HasSchema(type))
                {
                    var schemaGenerator = new RootTypeJsonSchemaGenerator(_service, Settings);
                    schemaGenerator.Generate <JsonSchema4>(type, schemaResolver);
                }

                schema.SchemaReference = schemaResolver.GetSchema(type);
            }
        }
        /// <summary>Generates the properties for the given type and schema.</summary>
        /// <typeparam name="TSchemaType">The type of the schema type.</typeparam>
        /// <param name="type">The types.</param>
        /// <param name="schema">The properties</param>
        /// <param name="rootSchema">The root schema.</param>
        /// <param name="schemaDefinitionAppender"></param>
        /// <param name="schemaResolver">The schema resolver.</param>
        protected override void GenerateObject <TSchemaType>(Type type, TSchemaType schema, JsonSchema4 rootSchema, ISchemaDefinitionAppender schemaDefinitionAppender, ISchemaResolver schemaResolver)
        {
            if (_isRootType)
            {
                _isRootType = false;
                base.GenerateObject(type, schema, rootSchema, _schemaDefinitionAppender, schemaResolver);
            }
            else
            {
                if (!schemaResolver.HasSchema(type, false))
                {
                    var schemaGenerator = new RootTypeJsonSchemaGenerator(_service, _schemaDefinitionAppender, Settings);
                    schemaGenerator.Generate(type, rootSchema, null, _schemaDefinitionAppender, schemaResolver);
                }

                schema.SchemaReference = schemaResolver.GetSchema(type, false);
            }
        }
        /// <summary>Generates the properties for the given type and schema.</summary>
        /// <typeparam name="TSchemaType">The type of the schema type.</typeparam>
        /// <param name="type">The types.</param>
        /// <param name="schema">The properties</param>
        /// <param name="schemaResolver"></param>
        /// <param name="schemaDefinitionAppender"></param>
        protected override void GenerateObject <TSchemaType>(Type type, TSchemaType schema, ISchemaResolver schemaResolver, ISchemaDefinitionAppender schemaDefinitionAppender)
        {
            if (_isRootType)
            {
                _isRootType = false;
                base.GenerateObject(type, schema, schemaResolver, schemaDefinitionAppender);
                _isRootType = true;
            }
            else
            {
                if (!schemaResolver.HasSchema(type, false))
                {
                    _isRootType = true;
                    Generate(type, schemaResolver, schemaDefinitionAppender);
                    _isRootType = false;
                }

                schema.SchemaReference = schemaResolver.GetSchema(type, false);
            }
        }
Example #10
0
        /// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary>
        /// <param name="type">The type.</param>
        /// <param name="parentAttributes">The parent property or parameter attributes.</param>
        /// <param name="schemaResolver"></param>
        /// <param name="schemaDefinitionAppender"></param>
        /// <returns>The schema.</returns>
        /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception>
        public virtual TSchemaType Generate <TSchemaType>(Type type, IEnumerable <Attribute> parentAttributes,
                                                          ISchemaResolver schemaResolver, ISchemaDefinitionAppender schemaDefinitionAppender)
            where TSchemaType : JsonSchema4, new()
        {
            var schema = HandleSpecialTypes <TSchemaType>(type, schemaResolver);

            if (schema != null)
            {
                return(schema);
            }

            schema = new TSchemaType();

            if (schemaDefinitionAppender.RootObject == null)
            {
                schemaDefinitionAppender.RootObject = schema;
            }

            ApplyExtensionDataAttributes(schema, type, parentAttributes);

            var typeDescription = JsonObjectTypeDescription.FromType(type, parentAttributes, Settings.DefaultEnumHandling);

            if (typeDescription.Type.HasFlag(JsonObjectType.Object))
            {
                if (typeDescription.IsDictionary)
                {
                    typeDescription.ApplyType(schema);
                    GenerateDictionary(type, schema, schemaResolver, schemaDefinitionAppender);
                }
                else
                {
                    if (schemaResolver.HasSchema(type, false))
                    {
                        schema.SchemaReference = schemaResolver.GetSchema(type, false);
                        return(schema);
                    }

                    if (schema.GetType() == typeof(JsonSchema4))
                    {
                        typeDescription.ApplyType(schema);

                        schema.TypeNameRaw = ReflectionExtensions.GetSafeTypeName(type);
                        schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes());

                        GenerateObject(type, schema, schemaResolver, schemaDefinitionAppender);
                    }
                    else
                    {
                        schema.SchemaReference = Generate <JsonSchema4>(type, parentAttributes, schemaResolver, schemaDefinitionAppender);
                        return(schema);
                    }
                }
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                var isIntegerEnumeration = typeDescription.Type == JsonObjectType.Integer;
                if (schemaResolver.HasSchema(type, isIntegerEnumeration))
                {
                    schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration);
                    return(schema);
                }

                if (schema.GetType() == typeof(JsonSchema4))
                {
                    LoadEnumerations(type, schema, typeDescription);

                    typeDescription.ApplyType(schema);

                    schema.TypeNameRaw = ReflectionExtensions.GetSafeTypeName(type);
                    schema.Description = type.GetXmlSummary();

                    schemaResolver.AddSchema(type, isIntegerEnumeration, schema);
                }
                else
                {
                    schema.SchemaReference = Generate <JsonSchema4>(type, parentAttributes, schemaResolver, schemaDefinitionAppender);
                    return(schema);
                }
            }
            else if (typeDescription.Type.HasFlag(JsonObjectType.Array))
            {
                typeDescription.ApplyType(schema);

                var itemType = type.GetEnumerableItemType();
                if (itemType == null)
                {
                    var jsonSchemaAttribute = type.GetTypeInfo().GetCustomAttribute <JsonSchemaAttribute>();
                    if (jsonSchemaAttribute?.ArrayItem != null)
                    {
                        schema.Item = Generate(jsonSchemaAttribute.ArrayItem, schemaResolver, schemaDefinitionAppender);
                    }
                    else
                    {
                        schema.Item = JsonSchema4.CreateAnySchema();
                    }
                }
                else
                {
                    if (itemType.GetTypeInfo().IsEnum)
                    {
                        schema.Item = new JsonSchema4 {
                            SchemaReference = Generate(itemType, schemaResolver, schemaDefinitionAppender)
                        }
                    }
                    ;
                    else
                    {
                        schema.Item = Generate(itemType, schemaResolver, schemaDefinitionAppender);
                    }
                }
            }
            else
            {
                typeDescription.ApplyType(schema);
            }

            return(schema);
        }
Example #11
0
        /// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary>
        /// <param name="type">The type.</param>
        /// <param name="rootSchema">The root schema.</param>
        /// <param name="parentAttributes">The parent property or parameter attributes.</param>
        /// <param name="schemaDefinitionAppender">The schema definition appender.</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns>The schema.</returns>
        /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception>
        public TSchemaType Generate <TSchemaType>(Type type, JsonSchema4 rootSchema, IEnumerable <Attribute> parentAttributes, ISchemaDefinitionAppender schemaDefinitionAppender, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            var schema = HandleSpecialTypes <TSchemaType>(type);

            if (schema != null)
            {
                return(schema);
            }

            schema = new TSchemaType();

            if (rootSchema == null)
            {
                rootSchema = schema;
            }

            var typeDescription = JsonObjectTypeDescription.FromType(type, parentAttributes, Settings.DefaultEnumHandling);

            typeDescription.ApplyType(schema);

            ApplyExtensionDataAttributes(schema, type, parentAttributes);

            if (schema.Type.HasFlag(JsonObjectType.Object))
            {
                if (typeDescription.IsDictionary)
                {
                    GenerateDictionary(type, rootSchema, schema, schemaDefinitionAppender, schemaResolver);
                }
                else
                {
                    schema.TypeNameRaw = GetTypeName(type);
                    if (schemaResolver.HasSchema(type, false))
                    {
                        schema.SchemaReference = schemaResolver.GetSchema(type, false);
                        return(schema);
                    }

                    if (schema.GetType() == typeof(JsonSchema4))
                    {
                        schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes());
                        GenerateObject(type, schema, rootSchema, schemaDefinitionAppender, schemaResolver);
                    }
                    else
                    {
                        schema.SchemaReference = Generate(type, rootSchema, parentAttributes, schemaDefinitionAppender, schemaResolver);
                        return(schema);
                    }
                }
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                var isIntegerEnumeration = typeDescription.Type == JsonObjectType.Integer;
                if (schemaResolver.HasSchema(type, isIntegerEnumeration))
                {
                    schema.Type            = typeDescription.Type;
                    schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration);
                    return(schema);
                }

                if (schema.GetType() == typeof(JsonSchema4))
                {
                    LoadEnumerations(type, schema, typeDescription);

                    schema.TypeNameRaw = GetTypeName(type);
                    schema.Description = type.GetXmlDocumentation();
                    schemaResolver.AddSchema(type, isIntegerEnumeration, schema);
                }
                else
                {
                    schema.SchemaReference = Generate(type, rootSchema, parentAttributes, schemaDefinitionAppender, schemaResolver);
                    return(schema);
                }
            }
            else if (schema.Type.HasFlag(JsonObjectType.Array))
            {
                schema.Type = JsonObjectType.Array;

                var genericTypeArguments = GetGenericTypeArguments(type);
                var itemType             = genericTypeArguments.Length == 0 ? type.GetElementType() : genericTypeArguments[0];
                if (itemType == null)
                {
                    schema.Item = JsonSchema4.CreateAnySchema();
                }
                else
                {
                    schema.Item = Generate(itemType, rootSchema, null, schemaDefinitionAppender, schemaResolver);
                }
            }

            return(schema);
        }
        private JsonSchema4 CreateAndAddSchema(SwaggerService service, Type type, IEnumerable <Attribute> parentAttributes, ISchemaResolver schemaResolver)
        {
            if (type.Name == "Task`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (type.Name == "JsonResult`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (IsFileResponse(type))
            {
                return new JsonSchema4 {
                           Type = JsonObjectType.File
                }
            }
            ;

            var schemaDefinitionAppender = new SwaggerServiceSchemaDefinitionAppender(service);
            var typeDescription          = JsonObjectTypeDescription.FromType(type, parentAttributes, Settings.DefaultEnumHandling);

            if (typeDescription.Type.HasFlag(JsonObjectType.Object) && !typeDescription.IsDictionary)
            {
                if (type == typeof(object))
                {
                    return(new JsonSchema4
                    {
                        Type = JsonObjectType.Object | JsonObjectType.Null,
                        AllowAdditionalProperties = false
                    });
                }

                if (!schemaResolver.HasSchema(type, false))
                {
                    var schemaGenerator = new RootTypeJsonSchemaGenerator(service, schemaDefinitionAppender, Settings);
                    schemaGenerator.Generate(type, null, null, schemaDefinitionAppender, schemaResolver);
                }

                return(new JsonSchema4
                {
                    Type = JsonObjectType.Object | JsonObjectType.Null,
                    SchemaReference = schemaResolver.GetSchema(type, false)
                });
            }

            if (typeDescription.Type.HasFlag(JsonObjectType.Array))
            {
                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                return(new JsonSchema4
                {
                    Type = JsonObjectType.Array | JsonObjectType.Null,
                    Item = CreateAndAddSchema(service, itemType, null, schemaResolver)
                });
            }

            var generator = new RootTypeJsonSchemaGenerator(service, schemaDefinitionAppender, Settings);

            return(generator.Generate(type, null, null, schemaDefinitionAppender, schemaResolver));
        }
    }
        private JsonSchema4 CreateAndAddSchema(SwaggerService service, Type type, bool mayBeNull, IEnumerable <Attribute> parentAttributes, ISchemaResolver schemaResolver)
        {
            if (type.Name == "Task`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (type.Name == "JsonResult`1")
            {
                type = type.GenericTypeArguments[0];
            }

            if (IsFileResponse(type))
            {
                return new JsonSchema4 {
                           Type = JsonObjectType.File
                }
            }
            ;

            var schemaDefinitionAppender = new SwaggerServiceSchemaDefinitionAppender(service, Settings.TypeNameGenerator);
            var typeDescription          = JsonObjectTypeDescription.FromType(type, parentAttributes, Settings.DefaultEnumHandling);

            if (typeDescription.Type.HasFlag(JsonObjectType.Object) && !typeDescription.IsDictionary)
            {
                if (type == typeof(object))
                {
                    return(new JsonSchema4
                    {
                        // IsNullable is directly set on SwaggerParameter or SwaggerResponse
                        Type = Settings.NullHandling == NullHandling.JsonSchema ? JsonObjectType.Object | JsonObjectType.Null : JsonObjectType.Object,
                        AllowAdditionalProperties = false
                    });
                }

                if (!schemaResolver.HasSchema(type, false))
                {
                    var schemaGenerator = new RootTypeJsonSchemaGenerator(service, schemaDefinitionAppender, Settings);
                    schemaGenerator.Generate(type, null, null, schemaDefinitionAppender, schemaResolver);
                }

                if (mayBeNull)
                {
                    if (Settings.NullHandling == NullHandling.JsonSchema)
                    {
                        var schema = new JsonSchema4();
                        schema.OneOf.Add(new JsonSchema4 {
                            Type = JsonObjectType.Null
                        });
                        schema.OneOf.Add(new JsonSchema4 {
                            SchemaReference = schemaResolver.GetSchema(type, false)
                        });
                        return(schema);
                    }
                    else
                    {
                        // IsNullable is directly set on SwaggerParameter or SwaggerResponse
                        return(new JsonSchema4 {
                            SchemaReference = schemaResolver.GetSchema(type, false)
                        });
                    }
                }
                else
                {
                    return new JsonSchema4 {
                               SchemaReference = schemaResolver.GetSchema(type, false)
                    }
                };
            }

            if (typeDescription.Type.HasFlag(JsonObjectType.Array))
            {
                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                return(new JsonSchema4
                {
                    // IsNullable is directly set on SwaggerParameter or SwaggerResponse
                    Type = Settings.NullHandling == NullHandling.JsonSchema ? JsonObjectType.Array | JsonObjectType.Null : JsonObjectType.Array,
                    Item = CreateAndAddSchema(service, itemType, false, null, schemaResolver)
                });
            }

            var generator = new RootTypeJsonSchemaGenerator(service, schemaDefinitionAppender, Settings);

            return(generator.Generate(type, null, null, schemaDefinitionAppender, schemaResolver));
        }
    }
}
Example #14
0
        /// <exception cref="InvalidOperationException">Could not find item type of array type.</exception>
        private TSchemaType Generate <TSchemaType>(Type type, PropertyInfo propertyInfo, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            if (type == typeof(object) || type == typeof(JObject))
            {
                return(new TSchemaType
                {
                    Type = JsonObjectType.Object,
                    AllowAdditionalProperties = true
                });
            }

            var schema = new TSchemaType();

            var typeDescription = JsonObjectTypeDescription.FromType(type);

            schema.Type   = typeDescription.Type;
            schema.Format = typeDescription.Format;

            if (schema.Type.HasFlag(JsonObjectType.Object))
            {
                if (typeDescription.IsDictionary)
                {
                    GenerateDictionary(type, schema, schemaResolver);
                }
                else
                {
                    schema.TypeName = GetTypeName(type);

                    if (schemaResolver.HasSchema(type, false))
                    {
                        schema.SchemaReference = schemaResolver.GetSchema(type, false);
                        return(schema);
                    }

                    schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes());

                    GenerateObject(type, schema, schemaResolver);
                }
            }
            else if (schema.Type.HasFlag(JsonObjectType.Array))
            {
                schema.Type = JsonObjectType.Array;

                var genericTypeArguments = GetGenericTypeArguments(type);
                var itemType             = genericTypeArguments.Length == 0 ? type.GetElementType() : genericTypeArguments[0];
                if (itemType == null)
                {
                    throw new InvalidOperationException("Could not find item type of array type '" + type.FullName + "'.");
                }

                schema.Item = Generate <JsonSchema4>(itemType, schemaResolver);
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                var isIntegerEnumeration = IsIntegerEnumeration(propertyInfo);

                if (schemaResolver.HasSchema(type, isIntegerEnumeration))
                {
                    schema.Type            = isIntegerEnumeration ? JsonObjectType.Integer : JsonObjectType.String;
                    schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration);
                    return(schema);
                }

                LoadEnumerations(type, schema, isIntegerEnumeration);

                schema.TypeName = GetTypeName(type);
                schemaResolver.AddSchema(type, isIntegerEnumeration, schema);
            }

            return(schema);
        }
Example #15
0
        /// <summary>Generates and appends a schema from a given type.</summary>
        /// <param name="type">The type.</param>
        /// <param name="mayBeNull">if set to <c>true</c> [may be null].</param>
        /// <param name="parentAttributes">The parent attributes.</param>
        /// <returns></returns>
        public JsonSchema4 GenerateAndAppendSchemaFromType(Type type, bool mayBeNull, IEnumerable<Attribute> parentAttributes)
        {
            if (type.Name == "Task`1")
                type = type.GenericTypeArguments[0];

            if (type.Name == "JsonResult`1")
                type = type.GenericTypeArguments[0];

            if (IsFileResponse(type))
                return new JsonSchema4 { Type = JsonObjectType.File };

            var typeDescription = JsonObjectTypeDescription.FromType(type, parentAttributes, _settings.DefaultEnumHandling);
            if (typeDescription.Type.HasFlag(JsonObjectType.Object) && !typeDescription.IsDictionary)
            {
                if (type == typeof(object))
                {
                    return new JsonSchema4
                    {
                        // IsNullable is directly set on SwaggerParameter or SwaggerResponse
                        Type = _settings.NullHandling == NullHandling.JsonSchema ? JsonObjectType.Object | JsonObjectType.Null : JsonObjectType.Object,
                        AllowAdditionalProperties = false
                    };
                }

                if (!_schemaResolver.HasSchema(type, false))
                    _schemaGenerator.Generate(type, _schemaResolver, _schemaDefinitionAppender);

                if (mayBeNull)
                {
                    if (_settings.NullHandling == NullHandling.JsonSchema)
                    {
                        var schema = new JsonSchema4();
                        schema.OneOf.Add(new JsonSchema4 { Type = JsonObjectType.Null });
                        schema.OneOf.Add(new JsonSchema4 { SchemaReference = _schemaResolver.GetSchema(type, false) });
                        return schema;
                    }
                    else
                    {
                        // TODO: Fix this bad design
                        // IsNullable must be directly set on SwaggerParameter or SwaggerResponse
                        return new JsonSchema4 { SchemaReference = _schemaResolver.GetSchema(type, false) };
                    }
                }
                else
                    return new JsonSchema4 { SchemaReference = _schemaResolver.GetSchema(type, false) };
            }

            if (typeDescription.Type.HasFlag(JsonObjectType.Array))
            {
                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                return new JsonSchema4
                {
                    // TODO: Fix this bad design
                    // IsNullable must be directly set on SwaggerParameter or SwaggerResponse
                    Type = _settings.NullHandling == NullHandling.JsonSchema ? JsonObjectType.Array | JsonObjectType.Null : JsonObjectType.Array,
                    Item = GenerateAndAppendSchemaFromType(itemType, false, null)
                };
            }

            return _schemaGenerator.Generate(type, _schemaResolver, _schemaDefinitionAppender);
        }
        /// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary>
        /// <typeparam name="TSchemaType">The type of the schema type.</typeparam>
        /// <param name="type">The type.</param>
        /// <param name="parentAttributes">The parent property or parameter attributes.</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns>The schema.</returns>
        /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception>
        /// <exception cref="InvalidOperationException">Could not find item type of array type.</exception>
        public TSchemaType Generate <TSchemaType>(Type type, IEnumerable <Attribute> parentAttributes, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            var schema = HandleSpecialTypes <TSchemaType>(type);

            if (schema != null)
            {
                return(schema);
            }

            schema = new TSchemaType();

            var typeDescription = JsonObjectTypeDescription.FromType(type);

            schema.Type   = typeDescription.Type;
            schema.Format = typeDescription.Format;

            if (schema.Type.HasFlag(JsonObjectType.Object))
            {
                if (typeDescription.IsDictionary)
                {
                    GenerateDictionary(type, schema, schemaResolver);
                }
                else
                {
                    schema.TypeName = GetTypeName(type);

                    if (schemaResolver.HasSchema(type, false))
                    {
                        schema.SchemaReference = schemaResolver.GetSchema(type, false);
                        return(schema);
                    }

                    schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes());

                    GenerateObject(type, schema, schemaResolver);
                }
            }
            else if (schema.Type.HasFlag(JsonObjectType.Array))
            {
                schema.Type = JsonObjectType.Array;

                var genericTypeArguments = GetGenericTypeArguments(type);
                var itemType             = genericTypeArguments.Length == 0 ? type.GetElementType() : genericTypeArguments[0];
                if (itemType == null)
                {
                    throw new InvalidOperationException("Could not find item type of array type '" + type.FullName + "'.");
                }

                schema.Item = Generate <JsonSchema4>(itemType, schemaResolver);
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                var isIntegerEnumeration = IsIntegerEnumeration(parentAttributes) || HasStringEnumConverter(type.GetTypeInfo().GetCustomAttributes());

                if (schemaResolver.HasSchema(type, isIntegerEnumeration))
                {
                    schema.Type            = isIntegerEnumeration ? JsonObjectType.Integer : JsonObjectType.String;
                    schema.SchemaReference = schemaResolver.GetSchema(type, isIntegerEnumeration);
                    return(schema);
                }

                LoadEnumerations(type, schema, isIntegerEnumeration, parentAttributes);

                schema.TypeName = GetTypeName(type);
                schemaResolver.AddSchema(type, isIntegerEnumeration, schema);
            }

            return(schema);
        }
        /// <summary>Generates a <see cref="JsonSchema4" /> object for the given type and adds the mapping to the given resolver.</summary>
        /// <typeparam name="TSchemaType">The type of the schema type.</typeparam>
        /// <param name="type">The type.</param>
        /// <param name="schemaResolver">The schema resolver.</param>
        /// <returns>The schema.</returns>
        /// <exception cref="InvalidOperationException">Could not find value type of dictionary type.</exception>
        /// <exception cref="InvalidOperationException">Could not find item type of enumeration type.</exception>
        public TSchemaType Generate <TSchemaType>(Type type, ISchemaResolver schemaResolver)
            where TSchemaType : JsonSchema4, new()
        {
            var schema = new TSchemaType();

            var typeDescription = JsonObjectTypeDescription.FromType(type);

            schema.Type   = typeDescription.Type;
            schema.Format = typeDescription.Format;

            if (schema.Type.HasFlag(JsonObjectType.Object))
            {
                if (typeDescription.IsDictionary)
                {
                    GenerateDictionary(type, schema, schemaResolver);
                }
                else
                {
                    if (type == typeof(object))
                    {
                        return(new TSchemaType
                        {
                            Type = JsonObjectType.Object,
                            AllowAdditionalProperties = false
                        });
                    }

                    schema.TypeName = GetTypeName(type);

                    if (schemaResolver.HasSchema(type))
                    {
                        schema.SchemaReference = schemaResolver.GetSchema(type);
                        return(schema);
                    }

                    schema.Description = GetDescription(type.GetTypeInfo(), type.GetTypeInfo().GetCustomAttributes());

                    GenerateObject(type, schema, schemaResolver);
                    GenerateInheritance(type, schema, schemaResolver);
                }
            }
            else if (schema.Type.HasFlag(JsonObjectType.Array))
            {
                schema.Type = JsonObjectType.Array;

                var itemType = type.GenericTypeArguments.Length == 0 ? type.GetElementType() : type.GenericTypeArguments[0];
                if (itemType == null)
                {
                    throw new InvalidOperationException("Could not find item type of enumeration type '" + type.FullName + "'.");
                }

                schema.Item = Generate <JsonSchema4>(itemType, schemaResolver);
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                if (schemaResolver.HasSchema(type))
                {
                    schema.SchemaReference = schemaResolver.GetSchema(type);
                    return(schema);
                }

                dynamic jsonConverterAttribute = type.GetTypeInfo().GetCustomAttributes()
                                                 .SingleOrDefault(a => a.GetType().Name == "JsonConverterAttribute");

                if (jsonConverterAttribute != null)
                {
                    var converterType = (Type)jsonConverterAttribute.ConverterType;
                    if (converterType.Name == "StringEnumConverter")
                    {
                        LoadEnumerations(type, schema);
                    }
                    else if (Settings.DefaultEnumHandling == EnumHandling.String)
                    {
                        LoadEnumerations(type, schema);
                    }
                }
                else if (Settings.DefaultEnumHandling == EnumHandling.String)
                {
                    LoadEnumerations(type, schema);
                }

                schema.TypeName = type.Name;
                schemaResolver.AddSchema(type, schema);
            }

            return(schema);
        }