/// <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; } }
/// <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; } }