private void PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired)
        {
            schema.Title       = GetTitle(contract.NonNullableUnderlyingType);
            schema.Description = GetDescription(contract.NonNullableUnderlyingType);

            JsonConverter converter = contract.Converter ?? contract.InternalConverter;

            if (converter != null)
            {
                schema.Type = null;
            }
            else
            {
                switch (contract.ContractType)
                {
                case JsonContractType.Object:
                    if (schema.Id == null)
                    {
                        schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false);
                    }

                    schema.Type = AddNullType(JSchemaType.Object, valueRequired);
                    GenerateObjectSchema(schema, contract.NonNullableUnderlyingType, (JsonObjectContract)contract);
                    break;

                case JsonContractType.Array:
                    if (schema.Id == null)
                    {
                        schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false);
                    }

                    schema.Type         = AddNullType(JSchemaType.Array, valueRequired);
                    schema.MinimumItems = DataAnnotationHelpers.GetMinLength(memberProperty);
                    schema.MaximumItems = DataAnnotationHelpers.GetMaxLength(memberProperty);

                    JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(contract.NonNullableUnderlyingType);

                    Required?required = null;
                    if (arrayAttribute != null && !arrayAttribute.AllowNullItems)
                    {
                        required = Required.Always;
                    }

                    Type collectionItemType = ReflectionUtils.GetCollectionItemType(contract.NonNullableUnderlyingType);
                    if (collectionItemType != null)
                    {
                        schema.Items.Add(GenerateInternal(collectionItemType, required, null, (JsonArrayContract)contract, null));
                    }
                    break;

                case JsonContractType.Primitive:
                    schema.Type = GetJSchemaType(contract.UnderlyingType, valueRequired);

                    if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String))
                    {
                        int minimumLength;
                        int maximumLength;
                        if (DataAnnotationHelpers.GetStringLength(memberProperty, out minimumLength, out maximumLength))
                        {
                            schema.MinimumLength = minimumLength;
                            schema.MaximumLength = maximumLength;
                        }
                        else
                        {
                            schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty);
                            schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty);
                        }

                        schema.Pattern = DataAnnotationHelpers.GetPattern(memberProperty);
                        schema.Format  = DataAnnotationHelpers.GetFormat(memberProperty);
                    }
                    if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Number) || JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Integer))
                    {
                        double minimum;
                        double maximum;
                        if (DataAnnotationHelpers.GetRange(memberProperty, out minimum, out maximum))
                        {
                            schema.Minimum = minimum;
                            schema.Maximum = maximum;
                        }
                    }

                    if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Integer) &&
                        contract.NonNullableUnderlyingType.IsEnum() &&
                        ReflectionUtils.GetAttribute <FlagsAttribute>(contract.NonNullableUnderlyingType) == null)
                    {
                        if ((schema.Type & JSchemaType.Null) == JSchemaType.Null)
                        {
                            schema.Enum.Add(JValue.CreateNull());
                        }

                        IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(contract.NonNullableUnderlyingType);
                        foreach (EnumValue <long> enumValue in enumValues)
                        {
                            JToken value = JToken.FromObject(enumValue.Value);

                            schema.Enum.Add(value);
                        }
                    }

                    Type enumDataType = DataAnnotationHelpers.GetEnumDataType(memberProperty);
                    if (enumDataType != null && CollectionUtils.IsNullOrEmpty(schema._enum))
                    {
                        IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(enumDataType);
                        foreach (EnumValue <long> enumValue in enumValues)
                        {
                            JToken value = (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String))
                                    ? enumValue.Name
                                    : JToken.FromObject(enumValue.Value);

                            schema.Enum.Add(value);
                        }
                    }
                    break;

                case JsonContractType.String:
                    JSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
                            ? JSchemaType.String
                            : AddNullType(JSchemaType.String, valueRequired);

                    schema.Type          = schemaType;
                    schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty);
                    schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty);
                    break;

                case JsonContractType.Dictionary:
                    schema.Type = AddNullType(JSchemaType.Object, valueRequired);
                    schema.MinimumProperties = DataAnnotationHelpers.GetMinLength(memberProperty);
                    schema.MaximumProperties = DataAnnotationHelpers.GetMaxLength(memberProperty);

                    Type keyType;
                    Type valueType;
                    ReflectionUtils.GetDictionaryKeyValueTypes(contract.NonNullableUnderlyingType, out keyType, out valueType);

                    if (keyType != null)
                    {
                        JsonContract keyContract = _generator.ContractResolver.ResolveContract(keyType);

                        // can be converted to a string
                        if (keyContract.ContractType == JsonContractType.Primitive)
                        {
                            schema.AdditionalProperties = GenerateInternal(valueType, Required.Default, null, (JsonDictionaryContract)contract, null);
                        }
                    }
                    break;

                case JsonContractType.Serializable:
                    if (schema.Id == null)
                    {
                        schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false);
                    }

                    schema.Type = AddNullType(JSchemaType.Object, valueRequired);
                    schema.AllowAdditionalProperties = true;
                    break;

                case JsonContractType.Dynamic:
                case JsonContractType.Linq:
                    schema.Type = null;
                    break;

                default:
                    throw new JSchemaException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
                }
            }
        }
        private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
        {
            ValidationUtils.ArgumentNotNull(type, "type");

            string resolvedId = GetTypeId(type, false);
            string explicitId = GetTypeId(type, true);

            if (!string.IsNullOrEmpty(resolvedId))
            {
                JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
                if (resolvedSchema != null)
                {
                    // resolved schema is not null but referencing member allows nulls
                    // change resolved schema to allow nulls. hacky but what are ya gonna do?
                    if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null))
                    {
                        resolvedSchema.Type |= JsonSchemaType.Null;
                    }
                    if (required && resolvedSchema.Required != true)
                    {
                        resolvedSchema.Required = true;
                    }

                    return(resolvedSchema);
                }
            }

            // test for unresolved circular reference
            if (_stack.Any(tc => tc.Type == type))
            {
                throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }

            JsonContract  contract = ContractResolver.ResolveContract(type);
            JsonConverter converter;

            if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null)
            {
                JsonSchema converterSchema = converter.GetSchema();
                if (converterSchema != null)
                {
                    return(converterSchema);
                }
            }

            Push(new TypeSchema(type, new JsonSchema()));

            if (explicitId != null)
            {
                CurrentSchema.Id = explicitId;
            }

            if (required)
            {
                CurrentSchema.Required = true;
            }
            CurrentSchema.Title       = GetTitle(type);
            CurrentSchema.Description = GetDescription(type);

            if (converter != null)
            {
                // todo: Add GetSchema to JsonConverter and use here?
                CurrentSchema.Type = JsonSchemaType.Any;
            }
            else
            {
                switch (contract.ContractType)
                {
                case JsonContractType.Object:
                    CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
                    CurrentSchema.Id   = GetTypeId(type, false);
                    GenerateObjectSchema(type, (JsonObjectContract)contract);
                    break;

                case JsonContractType.Array:
                    CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);

                    CurrentSchema.Id = GetTypeId(type, false);

                    JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(type);
                    bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems);

                    Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                    if (collectionItemType != null)
                    {
                        CurrentSchema.Items = new List <JsonSchema>();
                        CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
                    }
                    break;

                case JsonContractType.Primitive:
                    CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);

                    if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum() && !type.IsDefined(typeof(FlagsAttribute), true))
                    {
                        CurrentSchema.Enum = new List <JToken>();

                        IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(type);
                        foreach (EnumValue <long> enumValue in enumValues)
                        {
                            JToken value = JToken.FromObject(enumValue.Value);

                            CurrentSchema.Enum.Add(value);
                        }
                    }
                    break;

                case JsonContractType.String:
                    JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
                            ? JsonSchemaType.String
                            : AddNullType(JsonSchemaType.String, valueRequired);

                    CurrentSchema.Type = schemaType;
                    break;

                case JsonContractType.Dictionary:
                    CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);

                    Type keyType;
                    Type valueType;
                    ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);

                    if (keyType != null)
                    {
                        JsonContract keyContract = ContractResolver.ResolveContract(keyType);

                        // can be converted to a string
                        if (keyContract.ContractType == JsonContractType.Primitive)
                        {
                            CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
                        }
                    }
                    break;

#if !(NETFX_CORE || PORTABLE || PORTABLE40)
                case JsonContractType.Serializable:
                    CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
                    CurrentSchema.Id   = GetTypeId(type, false);
                    GenerateISerializableContract(type, (JsonISerializableContract)contract);
                    break;
#endif
#if !(NET35 || NET20 || PORTABLE40)
                case JsonContractType.Dynamic:
#endif
                case JsonContractType.Linq:
                    CurrentSchema.Type = JsonSchemaType.Any;
                    break;

                default:
                    throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
                }
            }

            return(Pop().Schema);
        }
        private JsonSchema GenerateInternal(Type type, Required valueRequired, bool optional)
        {
            ValidationUtils.ArgumentNotNull(type, "type");

            string resolvedId = GetTypeId(type, false);
            string explicitId = GetTypeId(type, true);

            if (!string.IsNullOrEmpty(resolvedId))
            {
                JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
                if (resolvedSchema != null)
                {
                    // resolved schema is not null but referencing member allows nulls
                    // change resolved schema to allow nulls. hacky but what are ya gonna do?
                    if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null))
                    {
                        resolvedSchema.Type |= JsonSchemaType.Null;
                    }
                    if (optional && resolvedSchema.Optional != true)
                    {
                        resolvedSchema.Optional = true;
                    }

                    return(resolvedSchema);
                }
            }

            // test for unresolved circular reference
            if (_stack.Any(tc => tc.Type == type))
            {
                throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }

            JsonContract  contract = ContractResolver.ResolveContract(type);
            JsonConverter converter;

            if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null)
            {
                JsonSchema converterSchema = converter.GetSchema();
                if (converterSchema != null)
                {
                    return(converterSchema);
                }
            }

            Push(new TypeSchema(type, new JsonSchema()));

            if (explicitId != null)
            {
                CurrentSchema.Id = explicitId;
            }

            if (optional)
            {
                CurrentSchema.Optional = true;
            }
            CurrentSchema.Title       = GetTitle(type);
            CurrentSchema.Description = GetDescription(type);

            if (converter != null)
            {
                // todo: Add GetSchema to JsonConverter and use here?
                CurrentSchema.Type = JsonSchemaType.Any;
            }
            else if (contract is JsonDictionaryContract)
            {
                CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);

                Type keyType;
                Type valueType;
                ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);

                if (keyType != null)
                {
                    // can be converted to a string
                    if (typeof(IConvertible).IsAssignableFrom(keyType))
                    {
                        CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
                    }
                }
            }
            else if (contract is JsonArrayContract)
            {
                CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);

                CurrentSchema.Id = GetTypeId(type, false);

                JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : true;

                Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                if (collectionItemType != null)
                {
                    CurrentSchema.Items = new List <JsonSchema>();
                    CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
                }
            }
            else if (contract is JsonPrimitiveContract)
            {
                CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);

                if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
                {
                    CurrentSchema.Enum    = new List <JToken>();
                    CurrentSchema.Options = new Dictionary <JToken, string>();

                    EnumValues <long> enumValues = EnumUtils.GetNamesAndValues <long>(type);
                    foreach (EnumValue <long> enumValue in enumValues)
                    {
                        JToken value = JToken.FromObject(enumValue.Value);

                        CurrentSchema.Enum.Add(value);
                        CurrentSchema.Options.Add(value, enumValue.Name);
                    }
                }
            }
            else if (contract is JsonObjectContract)
            {
                CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
                CurrentSchema.Id   = GetTypeId(type, false);
                GenerateObjectSchema(type, (JsonObjectContract)contract);
            }
#if !SILVERLIGHT && !PocketPC
            else if (contract is JsonISerializableContract)
            {
                CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
                CurrentSchema.Id   = GetTypeId(type, false);
                GenerateISerializableContract(type, (JsonISerializableContract)contract);
            }
#endif
            else if (contract is JsonStringContract)
            {
                JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
                                      ? JsonSchemaType.String
                                      : AddNullType(JsonSchemaType.String, valueRequired);

                CurrentSchema.Type = schemaType;
            }
            else if (contract is JsonLinqContract)
            {
                CurrentSchema.Type = JsonSchemaType.Any;
            }
            else
            {
                throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
            }

            return(Pop().Schema);
        }
        private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
        {
            ValidationUtils.ArgumentNotNull(type, "type");
            string typeId  = this.GetTypeId(type, false);
            string typeId2 = this.GetTypeId(type, true);

            if (!string.IsNullOrEmpty(typeId))
            {
                JsonSchema schema = this._resolver.GetSchema(typeId);
                if (schema != null)
                {
                    if (valueRequired != Required.Always && !JsonSchemaGenerator.HasFlag(schema.Type, JsonSchemaType.Null))
                    {
                        schema.Type |= JsonSchemaType.Null;
                    }
                    if (required && schema.Required != true)
                    {
                        schema.Required = new bool?(true);
                    }
                    return(schema);
                }
            }
            if (this._stack.Any((JsonSchemaGenerator.TypeSchema tc) => tc.Type == type))
            {
                throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }
            JsonContract  jsonContract = this.ContractResolver.ResolveContract(type);
            JsonConverter jsonConverter;

            if ((jsonConverter = jsonContract.Converter) != null || (jsonConverter = jsonContract.InternalConverter) != null)
            {
                JsonSchema schema2 = jsonConverter.GetSchema();
                if (schema2 != null)
                {
                    return(schema2);
                }
            }
            this.Push(new JsonSchemaGenerator.TypeSchema(type, new JsonSchema()));
            if (typeId2 != null)
            {
                this.CurrentSchema.Id = typeId2;
            }
            if (required)
            {
                this.CurrentSchema.Required = new bool?(true);
            }
            this.CurrentSchema.Title       = this.GetTitle(type);
            this.CurrentSchema.Description = this.GetDescription(type);
            if (jsonConverter != null)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
            }
            else
            {
                switch (jsonContract.ContractType)
                {
                case JsonContractType.Object:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateObjectSchema(type, (JsonObjectContract)jsonContract);
                    goto IL_51E;

                case JsonContractType.Array:
                    {
                        this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Array, valueRequired));
                        this.CurrentSchema.Id   = this.GetTypeId(type, false);
                        JsonArrayAttribute jsonArrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                        bool flag = jsonArrayAttribute == null || jsonArrayAttribute.AllowNullItems;
                        Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                        if (collectionItemType != null)
                        {
                            this.CurrentSchema.Items = new List <JsonSchema>();
                            this.CurrentSchema.Items.Add(this.GenerateInternal(collectionItemType, (!flag) ? Required.Always : Required.Default, false));
                            goto IL_51E;
                        }
                        goto IL_51E;
                    }

                case JsonContractType.Primitive:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.GetJsonSchemaType(type, valueRequired));
                    if (!(this.CurrentSchema.Type == JsonSchemaType.Integer) || !type.IsEnum() || type.IsDefined(typeof(FlagsAttribute), true))
                    {
                        goto IL_51E;
                    }
                    this.CurrentSchema.Enum = new List <JToken>();
                    EnumValues <long> namesAndValues = EnumUtils.GetNamesAndValues <long>(type);
                    using (IEnumerator <EnumValue <long> > enumerator = namesAndValues.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            EnumValue <long> current = enumerator.Current;
                            JToken           item    = JToken.FromObject(current.Value);
                            this.CurrentSchema.Enum.Add(item);
                        }
                        goto IL_51E;
                    }
                    break;
                }

                case JsonContractType.String:
                    break;

                case JsonContractType.Dictionary:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    Type type2;
                    Type type3;
                    ReflectionUtils.GetDictionaryKeyValueTypes(type, out type2, out type3);
                    if (!(type2 != null))
                    {
                        goto IL_51E;
                    }
                    JsonContract jsonContract2 = this.ContractResolver.ResolveContract(type2);
                    if (jsonContract2.ContractType == JsonContractType.Primitive)
                    {
                        this.CurrentSchema.AdditionalProperties = this.GenerateInternal(type3, Required.Default, false);
                        goto IL_51E;
                    }
                    goto IL_51E;
                }

                case JsonContractType.Dynamic:
                case JsonContractType.Linq:
                    this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
                    goto IL_51E;

                case JsonContractType.Serializable:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateISerializableContract(type, (JsonISerializableContract)jsonContract);
                    goto IL_51E;

                default:
                    throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContract));
                }
                JsonSchemaType value = (!ReflectionUtils.IsNullable(jsonContract.UnderlyingType)) ? JsonSchemaType.String : this.AddNullType(JsonSchemaType.String, valueRequired);
                this.CurrentSchema.Type = new JsonSchemaType?(value);
            }
            IL_51E:
            return(this.Pop().Schema);
        }
Exemple #5
0
 private static void Test()
 {
     var asdf = new JsonArrayAttribute("5");
 }
Exemple #6
0
        private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
        {
            JsonConverter converter;

            ValidationUtils.ArgumentNotNull(type, "type");
            string typeId = this.GetTypeId(type, false);
            string str2   = this.GetTypeId(type, true);

            if (!string.IsNullOrEmpty(typeId))
            {
                JsonSchema schema = this._resolver.GetSchema(typeId);
                if (schema != null)
                {
                    if ((valueRequired != Required.Always) && !HasFlag(schema.Type, JsonSchemaType.Null))
                    {
                        schema.Type = ((JsonSchemaType)schema.Type) | JsonSchemaType.Null;
                    }
                    if (required)
                    {
                        bool?nullable3 = schema.Required;
                        bool flag      = true;
                        if ((nullable3.GetValueOrDefault() == flag) ? !nullable3.HasValue : true)
                        {
                            schema.Required = true;
                        }
                    }
                    return(schema);
                }
            }
            if (this._stack.Any <TypeSchema>(tc => tc.Type == type))
            {
                throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }
            JsonContract contract = this.ContractResolver.ResolveContract(type);

            if (((converter = contract.Converter) != null) || ((converter = contract.InternalConverter) != null))
            {
                JsonSchema schema = converter.GetSchema();
                if (schema != null)
                {
                    return(schema);
                }
            }
            this.Push(new TypeSchema(type, new JsonSchema()));
            if (str2 != null)
            {
                this.CurrentSchema.Id = str2;
            }
            if (required)
            {
                this.CurrentSchema.Required = true;
            }
            this.CurrentSchema.Title       = this.GetTitle(type);
            this.CurrentSchema.Description = this.GetDescription(type);
            if (converter != null)
            {
                this.CurrentSchema.Type = 0x7f;
            }
            else
            {
                switch (contract.ContractType)
                {
                case JsonContractType.Object:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateObjectSchema(type, (JsonObjectContract)contract);
                    goto Label_0516;

                case JsonContractType.Array:
                    {
                        this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Array, valueRequired));
                        this.CurrentSchema.Id   = this.GetTypeId(type, false);
                        JsonArrayAttribute cachedAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(type);
                        bool flag2 = (cachedAttribute == null) || cachedAttribute.AllowNullItems;
                        Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                        if (collectionItemType != null)
                        {
                            this.CurrentSchema.Items = new List <JsonSchema>();
                            this.CurrentSchema.Items.Add(this.GenerateInternal(collectionItemType, !flag2 ? Required.Always : Required.Default, false));
                        }
                        goto Label_0516;
                    }

                case JsonContractType.Primitive:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.GetJsonSchemaType(type, valueRequired));
                    JsonSchemaType?nullable = this.CurrentSchema.Type;
                    JsonSchemaType integer  = JsonSchemaType.Integer;
                    if ((!((((JsonSchemaType)nullable.GetValueOrDefault()) == integer) ? nullable.HasValue : false) || !type.IsEnum()) || type.IsDefined(typeof(FlagsAttribute), true))
                    {
                        goto Label_0516;
                    }
                    this.CurrentSchema.Enum = new List <JToken>();
                    using (IEnumerator <EnumValue <long> > enumerator = EnumUtils.GetNamesAndValues <long>(type).GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            JToken item = JToken.FromObject(enumerator.Current.Value);
                            this.CurrentSchema.Enum.Add(item);
                        }
                        goto Label_0516;
                    }
                }

                case JsonContractType.String:
                {
                    JsonSchemaType type5 = !ReflectionUtils.IsNullable(contract.UnderlyingType) ? JsonSchemaType.String : this.AddNullType(JsonSchemaType.String, valueRequired);
                    this.CurrentSchema.Type = new JsonSchemaType?(type5);
                    goto Label_0516;
                }

                case JsonContractType.Dictionary:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    ReflectionUtils.GetDictionaryKeyValueTypes(type, out Type type6, out Type type7);
                    if ((type6 != null) && (this.ContractResolver.ResolveContract(type6).ContractType == JsonContractType.Primitive))
                    {
                        this.CurrentSchema.AdditionalProperties = this.GenerateInternal(type7, Required.Default, false);
                    }
                    goto Label_0516;

                case JsonContractType.Dynamic:
                case JsonContractType.Linq:
                    this.CurrentSchema.Type = 0x7f;
                    goto Label_0516;

                case JsonContractType.Serializable:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateISerializableContract(type, (JsonISerializableContract)contract);
                    goto Label_0516;
                }
                throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
            }
Label_0516:
            return(this.Pop().Schema);
        }
Exemple #7
0
        private JsonSchema GenerateInternal(Type type, bool valueRequired)
        {
            ValidationUtils.ArgumentNotNull(type, "type");

            string resolvedId = GetTypeId(type, false);
            string explicitId = GetTypeId(type, true);

            if (!string.IsNullOrEmpty(resolvedId))
            {
                JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
                if (resolvedSchema != null)
                {
                    return(resolvedSchema);
                }
            }

            // test for unresolved circular reference
            if (_stack.Any(tc => tc.Type == type))
            {
                throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }

            Push(new TypeSchema(type, new JsonSchema()));

            if (explicitId != null)
            {
                CurrentSchema.Id = explicitId;
            }

            CurrentSchema.Title       = GetTitle(type);
            CurrentSchema.Description = GetDescription(type);

            if (CollectionUtils.IsDictionaryType(type))
            {
                // To-Do: include null
                CurrentSchema.Type = JsonSchemaType.Object;

                Type keyType;
                Type valueType;
                ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);

                if (keyType != null)
                {
                    // can be converted to a string
                    if (typeof(IConvertible).IsAssignableFrom(keyType))
                    {
                        CurrentSchema.AdditionalProperties = GenerateInternal(valueType, false);
                    }
                }
            }
            else if (CollectionUtils.IsCollectionType(type))
            {
                // To-Do: include null
                CurrentSchema.Type = JsonSchemaType.Array;

                JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : false;

                Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                if (collectionItemType != null)
                {
                    CurrentSchema.Items = new List <JsonSchema>();
                    CurrentSchema.Items.Add(GenerateInternal(collectionItemType, !allowNullItem));
                }
            }
            else
            {
                CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);

                if (HasFlag(CurrentSchema.Type, JsonSchemaType.Object))
                {
                    CurrentSchema.Id = GetTypeId(type, false);

                    JsonObjectContract contract = ContractResolver.ResolveContract(type) as JsonObjectContract;

                    if (contract == null)
                    {
                        throw new Exception("Could not resolve contract for '{0}'.".FormatWith(CultureInfo.InvariantCulture, type));
                    }

                    CurrentSchema.Properties = new Dictionary <string, JsonSchema>();
                    foreach (JsonProperty property in contract.Properties)
                    {
                        if (!property.Ignored)
                        {
                            Type       propertyMemberType = ReflectionUtils.GetMemberUnderlyingType(property.Member);
                            JsonSchema propertySchema     = GenerateInternal(propertyMemberType, property.Required);

                            if (property.DefaultValue != null)
                            {
                                propertySchema.Default = JToken.FromObject(property.DefaultValue);
                            }

                            CurrentSchema.Properties.Add(property.PropertyName, propertySchema);
                        }
                    }

                    if (type.IsSealed)
                    {
                        CurrentSchema.AllowAdditionalProperties = false;
                    }
                }
                else if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
                {
                    CurrentSchema.Enum    = new List <JToken>();
                    CurrentSchema.Options = new Dictionary <JToken, string>();

                    EnumValues <ulong> enumValues = EnumUtils.GetNamesAndValues <ulong>(type);
                    foreach (EnumValue <ulong> enumValue in enumValues)
                    {
                        JToken value = JToken.FromObject(enumValue.Value);

                        CurrentSchema.Enum.Add(value);
                        CurrentSchema.Options.Add(value, enumValue.Name);
                    }
                }
            }

            return(Pop().Schema);
        }
Exemple #8
0
        // Token: 0x060013CD RID: 5069 RVA: 0x00068C14 File Offset: 0x00066E14
        private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
        {
            ValidationUtils.ArgumentNotNull(type, "type");
            string typeId  = this.GetTypeId(type, false);
            string typeId2 = this.GetTypeId(type, true);

            if (!StringUtils.IsNullOrEmpty(typeId))
            {
                JsonSchema schema = this._resolver.GetSchema(typeId);
                if (schema != null)
                {
                    if (valueRequired != Required.Always && !JsonSchemaGenerator.HasFlag(schema.Type, JsonSchemaType.Null))
                    {
                        schema.Type |= JsonSchemaType.Null;
                    }
                    if (required)
                    {
                        bool?required2 = schema.Required;
                        if (!(required2.GetValueOrDefault() & required2 != null))
                        {
                            schema.Required = new bool?(true);
                        }
                    }
                    return(schema);
                }
            }
            if (this._stack.Any((JsonSchemaGenerator.TypeSchema tc) => tc.Type == type))
            {
                throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }
            JsonContract jsonContract = this.ContractResolver.ResolveContract(type);
            bool         flag         = (jsonContract.Converter ?? jsonContract.InternalConverter) != null;

            this.Push(new JsonSchemaGenerator.TypeSchema(type, new JsonSchema()));
            if (typeId2 != null)
            {
                this.CurrentSchema.Id = typeId2;
            }
            if (required)
            {
                this.CurrentSchema.Required = new bool?(true);
            }
            this.CurrentSchema.Title       = this.GetTitle(type);
            this.CurrentSchema.Description = this.GetDescription(type);
            if (flag)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
            }
            else
            {
                switch (jsonContract.ContractType)
                {
                case JsonContractType.Object:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateObjectSchema(type, (JsonObjectContract)jsonContract);
                    break;

                case JsonContractType.Array:
                    {
                        this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Array, valueRequired));
                        this.CurrentSchema.Id   = this.GetTypeId(type, false);
                        JsonArrayAttribute cachedAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(type);
                        bool flag2 = cachedAttribute == null || cachedAttribute.AllowNullItems;
                        Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                        if (collectionItemType != null)
                        {
                            this.CurrentSchema.Items = new List <JsonSchema>();
                            this.CurrentSchema.Items.Add(this.GenerateInternal(collectionItemType, (!flag2) ? Required.Always : Required.Default, false));
                        }
                        break;
                    }

                case JsonContractType.Primitive:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.GetJsonSchemaType(type, valueRequired));
                    JsonSchemaType?type2 = this.CurrentSchema.Type;
                    if ((type2.GetValueOrDefault() == JsonSchemaType.Integer & type2 != null) && type.IsEnum() && !type.IsDefined(typeof(FlagsAttribute), true))
                    {
                        this.CurrentSchema.Enum = new List <JToken>();
                        EnumInfo enumValuesAndNames = EnumUtils.GetEnumValuesAndNames(type);
                        for (int i = 0; i < enumValuesAndNames.Names.Length; i++)
                        {
                            ulong  value = enumValuesAndNames.Values[i];
                            JToken item  = JToken.FromObject(Enum.ToObject(type, value));
                            this.CurrentSchema.Enum.Add(item);
                        }
                    }
                    break;
                }

                case JsonContractType.String:
                {
                    JsonSchemaType value2 = (!ReflectionUtils.IsNullable(jsonContract.UnderlyingType)) ? JsonSchemaType.String : this.AddNullType(JsonSchemaType.String, valueRequired);
                    this.CurrentSchema.Type = new JsonSchemaType?(value2);
                    break;
                }

                case JsonContractType.Dictionary:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    Type type3;
                    Type type4;
                    ReflectionUtils.GetDictionaryKeyValueTypes(type, out type3, out type4);
                    if (type3 != null && this.ContractResolver.ResolveContract(type3).ContractType == JsonContractType.Primitive)
                    {
                        this.CurrentSchema.AdditionalProperties = this.GenerateInternal(type4, Required.Default, false);
                    }
                    break;
                }

                case JsonContractType.Dynamic:
                case JsonContractType.Linq:
                    this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
                    break;

                case JsonContractType.Serializable:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateISerializableContract(type, (JsonISerializableContract)jsonContract);
                    break;

                default:
                    throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContract));
                }
            }
            return(this.Pop().Schema);
        }
        private void PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired)
        {
            schema.Title       = GetTitle(contract.NonNullableUnderlyingType, memberProperty);
            schema.Description = GetDescription(contract.NonNullableUnderlyingType, memberProperty);

            JsonConverter converter;

            if (contract.Converter != null && contract.Converter.CanWrite)
            {
                converter = contract.Converter;
            }
            else if (contract.InternalConverter != null && contract.InternalConverter.CanWrite)
            {
                converter = contract.InternalConverter;
            }
            else
            {
                converter = null;
            }

            if (converter != null)
            {
                schema.Type = null;
            }
            else
            {
                switch (contract.ContractType)
                {
                case JsonContractType.Object:
                    if (contract.NonNullableUnderlyingType == typeof(object))
                    {
                        PopulatePrimativeSchema(schema, contract, memberProperty, valueRequired);
                    }
                    else
                    {
                        if (schema.Id == null)
                        {
                            schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false);
                        }

                        schema.Type = AddNullType(JSchemaType.Object, valueRequired);
                        GenerateObjectSchema(schema, contract.NonNullableUnderlyingType, (JsonObjectContract)contract);
                    }
                    break;

                case JsonContractType.Array:
                    if (schema.Id == null)
                    {
                        schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false);
                    }

                    schema.Type         = AddNullType(JSchemaType.Array, valueRequired);
                    schema.MinimumItems = DataAnnotationHelpers.GetMinLength(memberProperty);
                    schema.MaximumItems = DataAnnotationHelpers.GetMaxLength(memberProperty);

                    JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(contract.NonNullableUnderlyingType);

                    Required?required = null;
                    if (arrayAttribute != null && !arrayAttribute.AllowNullItems)
                    {
                        required = Required.Always;
                    }

                    Type collectionItemType = ReflectionUtils.GetCollectionItemType(contract.NonNullableUnderlyingType);
                    if (collectionItemType != null)
                    {
                        schema.Items.Add(GenerateInternal(collectionItemType, required, null, (JsonArrayContract)contract, null));
                    }
                    break;

                case JsonContractType.Primitive:
                    PopulatePrimativeSchema(schema, contract, memberProperty, valueRequired);
                    break;

                case JsonContractType.String:
                    JSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
                            ? JSchemaType.String
                            : AddNullType(JSchemaType.String, valueRequired);

                    schema.Type          = schemaType;
                    schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty);
                    schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty);
                    break;

                case JsonContractType.Dictionary:
                    schema.Type = AddNullType(JSchemaType.Object, valueRequired);
                    schema.MinimumProperties = DataAnnotationHelpers.GetMinLength(memberProperty);
                    schema.MaximumProperties = DataAnnotationHelpers.GetMaxLength(memberProperty);

                    ReflectionUtils.GetDictionaryKeyValueTypes(contract.NonNullableUnderlyingType, out Type keyType, out Type valueType);

                    if (keyType != null)
                    {
                        JsonContract keyContract = _generator.ContractResolver.ResolveContract(keyType);

                        // can be converted to a string
                        if (keyContract.ContractType == JsonContractType.Primitive)
                        {
                            schema.AdditionalProperties = GenerateInternal(valueType, _generator.DefaultRequired, null, (JsonDictionaryContract)contract, null);
                        }
                    }
                    break;

                case JsonContractType.Serializable:
                    if (schema.Id == null)
                    {
                        schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false);
                    }

                    schema.Type = AddNullType(JSchemaType.Object, valueRequired);
                    schema.AllowAdditionalProperties = true;
                    break;

                case JsonContractType.Dynamic:
                case JsonContractType.Linq:
                    schema.Type = null;
                    break;

                default:
                    throw new JSchemaException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
                }
            }
        }