/// <summary>
        /// Builds an object from a <see cref="JsonValue"/>.
        /// </summary>
        /// <param name="json">The <see cref="JsonValue"/> representation of the object.</param>
        /// <param name="serializer">The <see cref="JsonSerializer"/> instance to use for additional serialization of values.</param>
        public virtual void FromJson(JsonValue json, JsonSerializer serializer)
        {
            var obj = json.Object;

            Id = obj.TryGetString("id");
            var uriFolder = DocumentPath?.OriginalString.EndsWith("/") ?? true ? DocumentPath : DocumentPath?.GetParentUri();

            if (!string.IsNullOrWhiteSpace(Id) &&
                (Uri.TryCreate(Id, UriKind.Absolute, out Uri uri) || Uri.TryCreate(uriFolder + Id, UriKind.Absolute, out uri)))
            {
                DocumentPath = uri;
                JsonSchemaRegistry.Register(this);
            }
            Schema      = obj.TryGetString("$schema");
            Title       = obj.TryGetString("title");
            Description = obj.TryGetString("description");
            if (obj.ContainsKey("default"))
            {
                Default = obj["default"];
            }
            MultipleOf       = obj.TryGetNumber("multipleOf");
            Maximum          = obj.TryGetNumber("maximum");
            ExclusiveMaximum = obj.TryGetBoolean("exclusiveMaximum");
            Minimum          = obj.TryGetNumber("minimum");
            ExclusiveMinimum = obj.TryGetBoolean("exclusiveMinimum");
            MaxLength        = (uint?)obj.TryGetNumber("maxLength");
            MinLength        = (uint?)obj.TryGetNumber("minLength");
            Pattern          = obj.TryGetString("pattern");
            if (obj.ContainsKey("additionalItems"))
            {
                if (obj["additionalItems"].Type == JsonValueType.Boolean)
                {
                    AdditionalItems = obj["additionalItems"].Boolean ? AdditionalItems.True : AdditionalItems.False;
                }
                else
                {
                    AdditionalItems = new AdditionalItems {
                        Definition = _ReadSchema(obj["additionalItems"])
                    }
                };
            }
            MaxItems = (uint?)obj.TryGetNumber("maxItems");
            MinItems = (uint?)obj.TryGetNumber("minItems");
            if (obj.ContainsKey("items"))
            {
                Items = JsonSchemaFactory.FromJson(obj["items"], DocumentPath);
            }
            UniqueItems   = obj.TryGetBoolean("uniqueItems");
            MaxProperties = (uint?)obj.TryGetNumber("maxProperties");
            MinProperties = (uint?)obj.TryGetNumber("minProperties");
            if (obj.ContainsKey("properties"))
            {
                Properties = obj["properties"].Object.ToDictionary(kvp => kvp.Key, kvp => _ReadSchema(kvp.Value));
            }
            Required = obj.TryGetArray("required")?.Select(jv => jv.String).ToList();
            if (obj.ContainsKey("additionalProperties"))
            {
                if (obj["additionalProperties"].Type == JsonValueType.Boolean)
                {
                    AdditionalProperties = obj["additionalProperties"].Boolean ? AdditionalProperties.True : AdditionalProperties.False;
                }
                else
                {
                    AdditionalProperties = new AdditionalProperties {
                        Definition = _ReadSchema(obj["additionalProperties"])
                    }
                };
            }
            if (obj.ContainsKey("definitions"))
            {
                Definitions = obj["definitions"].Object.ToDictionary(kvp => kvp.Key, kvp => _ReadSchema(kvp.Value));
            }
            if (obj.ContainsKey("patternProperties"))
            {
                var patterns = obj["patternProperties"].Object;
                PatternProperties = patterns.ToDictionary(kvp => new Regex(kvp.Key), kvp => _ReadSchema(kvp.Value));
            }
            if (obj.ContainsKey("dependencies"))
            {
                Dependencies = obj["dependencies"].Object.Select(v =>
                {
                    IJsonSchemaDependency dependency;
                    switch (v.Value.Type)
                    {
                    case JsonValueType.Object:
                        dependency = new SchemaDependency(v.Key, _ReadSchema(v.Value));
                        break;

                    case JsonValueType.Array:
                        if (!v.Value.Array.Any())
                        {
                            throw new ArgumentException("Property dependency must declare at least one property.");
                        }
                        dependency = new PropertyDependency(v.Key, v.Value.Array.Select(jv => jv.String));
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    return(dependency);
                });
            }
            if (obj.ContainsKey("enum"))
            {
                Enum = json.Object["enum"].Array.Select(jv => new EnumSchemaValue(jv));
            }
            if (obj.ContainsKey("type"))
            {
                Type = obj["type"].FromJson();
            }
            if (obj.ContainsKey("allOf"))
            {
                AllOf = obj["allOf"].Array.Select(_ReadSchema);
            }
            if (obj.ContainsKey("anyOf"))
            {
                AnyOf = json.Object["anyOf"].Array.Select(_ReadSchema);
            }
            if (obj.ContainsKey("oneOf"))
            {
                OneOf = obj["oneOf"].Array.Select(_ReadSchema);
            }
            if (obj.ContainsKey("not"))
            {
                Not = _ReadSchema(obj["not"]);
            }
            var formatKey = obj.TryGetString("format");

            Format = StringFormat.GetFormat(formatKey);
            var details = obj.Where(kvp => !_definedProperties.Contains(kvp.Key)).ToJson();

            if (details.Any())
            {
                ExtraneousDetails = details;
            }
        }
Exemple #2
0
        /// <summary>
        /// Builds an object from a <see cref="JsonValue"/>.
        /// </summary>
        /// <param name="json">The <see cref="JsonValue"/> representation of the object.</param>
        /// <param name="serializer">The <see cref="JsonSerializer"/> instance to use for additional serialization of values.</param>
        public virtual void FromJson(JsonValue json, JsonSerializer serializer)
        {
            if (json.Type == JsonValueType.Boolean)
            {
                BooleanSchemaDefinition = json.Boolean;
                return;
            }

            serializer = serializer ?? _schemaSerializer;

            var obj = json.Object;

            Id = obj.TryGetString("$id");
            var uriFolder = DocumentPath?.OriginalString.EndsWith("/") ?? true ? DocumentPath : DocumentPath?.GetParentUri();

            if (!string.IsNullOrWhiteSpace(Id) &&
                (Uri.TryCreate(Id, UriKind.Absolute, out Uri uri) || Uri.TryCreate(uriFolder + Id, UriKind.Absolute, out uri)))
            {
                DocumentPath = uri;
                JsonSchemaRegistry.Register(this);
            }
            Schema      = obj.TryGetString("$schema");
            Comment     = obj.TryGetString("$comment");
            Title       = obj.TryGetString("title");
            Description = obj.TryGetString("description");
            if (obj.ContainsKey("default"))
            {
                Default = obj["default"];
            }
            ReadOnly = obj.TryGetBoolean("readOnly");
            if (obj.ContainsKey("examples"))
            {
                Examples = json.Object["examples"].Array;
                Examples.EqualityStandard = ArrayEquality.ContentsEqual;
            }
            MultipleOf       = obj.TryGetNumber("multipleOf");
            Maximum          = obj.TryGetNumber("maximum");
            ExclusiveMaximum = obj.TryGetNumber("exclusiveMaximum");
            Minimum          = obj.TryGetNumber("minimum");
            ExclusiveMinimum = obj.TryGetNumber("exclusiveMinimum");
            MaxLength        = (uint?)obj.TryGetNumber("maxLength");
            MinLength        = (uint?)obj.TryGetNumber("minLength");
            Pattern          = obj.TryGetString("pattern");
            if (obj.ContainsKey("additionalItems"))
            {
                AdditionalItems = _ReadSchema(obj["additionalItems"]);
            }
            MaxItems = (uint?)obj.TryGetNumber("maxItems");
            MinItems = (uint?)obj.TryGetNumber("minItems");
            if (obj.ContainsKey("items"))
            {
                Items = _ReadSchema(obj["items"]);
            }
            UniqueItems = obj.TryGetBoolean("uniqueItems");
            if (obj.ContainsKey("contains"))
            {
                Contains = _ReadSchema(obj["contains"]);
            }
            MaxProperties = (uint?)obj.TryGetNumber("maxProperties");
            MinProperties = (uint?)obj.TryGetNumber("minProperties");
            if (obj.ContainsKey("properties"))
            {
                Properties = obj["properties"].Object.ToDictionary(kvp => kvp.Key, kvp => _ReadSchema(kvp.Value));
            }
            Required = obj.TryGetArray("required")?.Select(jv => jv.String).ToList();
            if (obj.ContainsKey("additionalProperties"))
            {
                AdditionalProperties = _ReadSchema(obj["additionalProperties"]);
            }
            if (obj.ContainsKey("definitions"))
            {
                Definitions = obj["definitions"].Object.ToDictionary(kvp => kvp.Key, kvp => _ReadSchema(kvp.Value));
            }
            if (obj.ContainsKey("patternProperties"))
            {
                var patterns = obj["patternProperties"].Object;
                PatternProperties = patterns.ToDictionary(kvp => new Regex(kvp.Key), kvp => _ReadSchema(kvp.Value));
            }
            if (obj.ContainsKey("dependencies"))
            {
                Dependencies = obj["dependencies"].Object.Select(v =>
                {
                    IJsonSchemaDependency dependency;
                    switch (v.Value.Type)
                    {
                    case JsonValueType.Boolean:
                    case JsonValueType.Object:
                        dependency = new SchemaDependency(v.Key, _ReadSchema(v.Value));
                        break;

                    case JsonValueType.Array:
                        dependency = new PropertyDependency(v.Key, v.Value.Array.Select(jv => jv.String));
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    return(dependency);
                });
            }
            if (obj.ContainsKey("propertyNames"))
            {
                PropertyNames = _ReadSchema(obj["propertyNames"]);
            }
            if (obj.ContainsKey("const"))
            {
                Const = obj["const"];
            }
            if (obj.ContainsKey("enum"))
            {
                Enum = json.Object["enum"].Array.Select(jv => new EnumSchemaValue(jv));
            }
            if (obj.ContainsKey("type"))
            {
                Type = obj["type"].FromJson();
            }
            if (obj.ContainsKey("allOf"))
            {
                AllOf = obj["allOf"].Array.Select(_ReadSchema);
            }
            if (obj.ContainsKey("anyOf"))
            {
                AnyOf = json.Object["anyOf"].Array.Select(_ReadSchema);
            }
            if (obj.ContainsKey("oneOf"))
            {
                OneOf = obj["oneOf"].Array.Select(_ReadSchema);
            }
            if (obj.ContainsKey("not"))
            {
                Not = _ReadSchema(obj["not"]);
            }
            var formatKey = obj.TryGetString("format");

            Format           = StringFormat.GetFormat(formatKey);
            ContentMediaType = obj.TryGetString("contentMediaType");
            var options    = serializer.Options;
            var newOptions = new JsonSerializerOptions(options)
            {
                CaseSensitiveDeserialization = false
            };

            serializer.Options = newOptions;
            if (obj.ContainsKey("contentEncoding"))
            {
                ContentEncoding = serializer.Deserialize <ContentEncoding>(obj["contentEncoding"]);
            }
            serializer.Options = options;
            if (obj.ContainsKey("if"))
            {
                If = _ReadSchema(obj["if"]);
            }
            if (obj.ContainsKey("then"))
            {
                Then = _ReadSchema(obj["then"]);
            }
            if (obj.ContainsKey("else"))
            {
                Else = _ReadSchema(obj["else"]);
            }
            var details = obj.Where(kvp => !_definedProperties.Contains(kvp.Key)).ToJson();

            if (details.Any())
            {
                ExtraneousDetails = details;
            }
        }