示例#1
0
 /// <summary>
 /// Used register any subschemas during validation.  Enables look-forward compatibility with `$ref` keywords.
 /// </summary>
 /// <param name="baseUri">The current base URI</param>
 /// <param name="localRegistry">A local schema registry to handle cases where <paramref name="baseUri"/> is null.</param>
 public void RegisterSubschemas(Uri baseUri, JsonSchemaRegistry localRegistry)
 {
     foreach (var schema in Values)
     {
         schema.RegisterSubschemas(baseUri, localRegistry);
     }
 }
        private JsonValue _Resolve(JsonValue root)
        {
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? DocumentPath?.OriginalString : referenceParts[0];
            var fragment       = referenceParts.Length > 1 ? referenceParts[1] : string.Empty;
            var jValue         = root;

            if (!string.IsNullOrWhiteSpace(address))
            {
                if (!Uri.TryCreate(address, UriKind.Absolute, out Uri absolute))
                {
                    address = Id + address;
                }
                if (DocumentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out absolute))
                {
                    var uriFolder = DocumentPath.OriginalString.EndsWith("/") ? DocumentPath : DocumentPath.GetParentUri();
                    absolute = new Uri(uriFolder, address);
                    address  = absolute.OriginalString;
                }
                jValue = JsonSchemaRegistry.Get(address).ToJson(null);
            }
            if (jValue == null)
            {
                return(root);
            }
            if (jValue == "#")
            {
                throw new ArgumentException("Cannot use a root reference as the base schema.");
            }

            Resolved = _ResolveLocalReference(jValue, fragment, string.IsNullOrWhiteSpace(address) ? null : new Uri(address));
            return(jValue);
        }
示例#3
0
        private void _ResolveReference(SchemaValidationContext context)
        {
            var documentPath   = context.BaseUri;
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? documentPath?.OriginalString : referenceParts[0];

            _resolvedFragment = referenceParts.Length > 1 ? JsonPointer.Parse(referenceParts[1]) : new JsonPointer();
            if (!string.IsNullOrWhiteSpace(address))
            {
                if (!Uri.TryCreate(address, UriKind.Absolute, out var absolute))
                {
                    address = context.Local.Id + address;
                }

                if (documentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out absolute))
                {
                    var uriFolder = documentPath.OriginalString.EndsWith("/") ? documentPath : documentPath.GetParentUri();
                    absolute = new Uri(uriFolder, address);
                    address  = absolute.OriginalString;
                }

                _resolvedRoot = JsonSchemaRegistry.Get(address);
            }
            else
            {
                _resolvedRoot = context.Root;
            }

            _ResolveLocalReference(_resolvedRoot?.DocumentPath ?? context.BaseUri);
        }
示例#4
0
        /// <summary>
        /// Creates a new instance of the <see cref="SchemaValidationContext"/> class by copying values from another instance.
        /// </summary>
        public SchemaValidationContext(SchemaValidationContext source)
            : this(source.Root,
                   source.Instance,
                   source.BaseRelativeLocation,
                   source.RelativeLocation,
                   source.InstanceLocation,
                   source.Options)
        {
            Local           = source.Local;
            Root            = source.Root;
            RecursiveAnchor = source.RecursiveAnchor;
            Instance        = source.Instance;

            ShouldTrackValidatedValues = source.ShouldTrackValidatedValues;

            _InitializeHashSet(ref _evaluatedPropertyNames, source._evaluatedPropertyNames);
            _InitializeHashSet(ref _locallyEvaluatedPropertyNames, source._locallyEvaluatedPropertyNames);
            _InitializeHashSet(ref _validatedIndices, source._validatedIndices);
            _InitializeHashSet(ref _locallyValidatedIndices, source._locallyValidatedIndices);

            LastEvaluatedIndex          = source.LastEvaluatedIndex;
            LocalTierLastEvaluatedIndex = source.LocalTierLastEvaluatedIndex;
            BaseUri                = source.BaseUri;
            InstanceLocation       = source.InstanceLocation;
            RelativeLocation       = source.RelativeLocation;
            BaseRelativeLocation   = source.BaseRelativeLocation;
            IsMetaSchemaValidation = source.IsMetaSchemaValidation;

            LocalRegistry = source.LocalRegistry;

            Options = source.Options;
        }
示例#5
0
        private void _ResolveReference(SchemaValidationContext context)
        {
            if (context.RecursiveAnchor != null)
            {
                var baseDocument = JsonSchemaRegistry.Get(context.BaseUri.OriginalString);
                if (baseDocument?.Get <RecursiveAnchorKeyword>() != null)
                {
                    _resolvedRoot = context.RecursiveAnchor;
                }
            }

            if (Reference.IsLocalSchemaId())
            {
                Resolved = context.LocalRegistry.GetLocal(Reference);
                if (Resolved != null)
                {
                    return;
                }
            }

            var documentPath   = _resolvedRoot?.DocumentPath ?? context.BaseUri;
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? documentPath?.OriginalString : referenceParts[0];

            _resolvedFragment = referenceParts.Length > 1 ? JsonPointer.Parse(referenceParts[1]) : new JsonPointer();
            if (_resolvedRoot == null)
            {
                if (!string.IsNullOrWhiteSpace(address))
                {
                    if (!Uri.TryCreate(address, UriKind.Absolute, out var absolute))
                    {
                        address = context.Local.Id + address;
                    }

                    if (documentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out absolute))
                    {
                        var uriFolder = documentPath.OriginalString.EndsWith("/") ? documentPath : documentPath.GetParentUri();
                        absolute = new Uri(uriFolder, address);
                        address  = absolute.OriginalString;
                    }

                    _resolvedRoot = JsonSchemaRegistry.Get(address);
                }
                else
                {
                    _resolvedRoot = context.Root;
                }
            }

            var wellKnown = JsonSchemaRegistry.GetWellKnown(Reference);

            if (wellKnown != null)
            {
                Resolved = wellKnown;
                return;
            }

            _ResolveLocalReference(_resolvedRoot?.DocumentPath ?? context.BaseUri);
        }
#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
        internal SchemaValidationContext(JsonSchema root,
                                         JsonValue instance,
                                         JsonPointer?baseRelativeLocation,
                                         JsonPointer relativeLocation,
                                         JsonPointer instanceLocation)
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
        {
            Root                 = root;
            Instance             = instance;
            BaseRelativeLocation = baseRelativeLocation;
            RelativeLocation     = relativeLocation;
            InstanceLocation     = instanceLocation;
            LocalRegistry        = new JsonSchemaRegistry();
        }
示例#7
0
        /// <summary>
        /// Provides the validation logic for this keyword.
        /// </summary>
        /// <param name="context">The context object.</param>
        /// <returns>Results object containing a final result and any errors that may have been found.</returns>
        public SchemaValidationResults Validate(SchemaValidationContext context)
        {
            if (!context.IsMetaSchemaValidation)
            {
                return(SchemaValidationResults.Null);
            }

            var nestedResults = new List <SchemaValidationResults>();

            var allVocabularies = this.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            allVocabularies[SchemaVocabularies.Core] = true;

            foreach (var kvp in allVocabularies)
            {
                var vocabulary = kvp.Key;
                if (vocabulary.MetaSchemaId == context.Local.Id)
                {
                    continue;
                }

                var required = kvp.Value;
                if (vocabulary.MetaSchemaId != null)
                {
                    var newContext = new SchemaValidationContext(context)
                    {
                        BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name, vocabulary.Id),
                        RelativeLocation     = context.RelativeLocation.CloneAndAppend(Name, vocabulary.Id),
                    };
                    var metaSchema = JsonSchemaRegistry.Get(vocabulary.MetaSchemaId);
                    if (metaSchema != null)
                    {
                        metaSchema.Validate(newContext);
                    }
                    else if (required)
                    {
                        nestedResults.Add(new SchemaValidationResults(Name, newContext));
                    }
                }
            }

            var results = new SchemaValidationResults(Name, context)
            {
                NestedResults = nestedResults,
                IsValid       = nestedResults.All(r => r.IsValid)
            };

            return(results);
        }
        /// <summary>
        /// Creates a new instance of the <see cref="SchemaValidationContext"/> class by copying values from another instance.
        /// </summary>
        public SchemaValidationContext(SchemaValidationContext source)
            : this()
        {
            Local           = source.Local;
            Root            = source.Root;
            RecursiveAnchor = source.RecursiveAnchor;
            Instance        = source.Instance;
            EvaluatedPropertyNames.AddRange(source.EvaluatedPropertyNames);
            LocallyEvaluatedPropertyNames.AddRange(source.LocallyEvaluatedPropertyNames);
            LastEvaluatedIndex          = source.LastEvaluatedIndex;
            LocalTierLastEvaluatedIndex = source.LocalTierLastEvaluatedIndex;
            BaseUri                = source.BaseUri;
            InstanceLocation       = source.InstanceLocation;
            RelativeLocation       = source.RelativeLocation;
            BaseRelativeLocation   = source.BaseRelativeLocation;
            IsMetaSchemaValidation = source.IsMetaSchemaValidation;

            LocalRegistry = source.LocalRegistry;
        }
示例#9
0
 /// <summary>
 /// Used register any subschemas during validation.  Enables look-forward compatibility with `$ref` keywords.
 /// </summary>
 /// <param name="baseUri">The current base URI</param>
 /// <param name="localRegistry">A local schema registry to handle cases where <paramref name="baseUri"/> is null.</param>
 public void RegisterSubschemas(Uri?baseUri, JsonSchemaRegistry localRegistry)
 {
     Value.RegisterSubschemas(baseUri, localRegistry);
 }
示例#10
0
 /// <summary>
 /// Used register any subschemas during validation.  Enables look-forward compatibility with `$ref` keywords.
 /// </summary>
 /// <param name="baseUri">The current base URI</param>
 /// <param name="localRegistry"></param>
 public void RegisterSubschemas(Uri?baseUri, JsonSchemaRegistry localRegistry)
 {
 }
示例#11
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)
        {
            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;
            }
        }
示例#12
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;
            }
        }
 internal SchemaValidationContext()
 {
     LocalRegistry = new JsonSchemaRegistry();
 }
示例#14
0
 /// <summary>
 /// Used register any subschemas during validation.  Enables look-forward compatibility with `$ref` keywords.
 /// </summary>
 /// <param name="baseUri">The current base URI</param>
 /// <param name="localRegistry"></param>
 /// <implementationNotes>
 /// If the dependency does not contain any schemas (e.g. `maximum`), this method is a no-op.
 /// </implementationNotes>
 public void RegisterSubschemas(Uri baseUri, JsonSchemaRegistry localRegistry)
 {
     _schema.RegisterSubschemas(baseUri, localRegistry);
 }
示例#15
0
        private void _ResolveReference(SchemaValidationContext context)
        {
            Log.Schema($"Resolving `{Reference}`");

            if (context.RecursiveAnchor != null)
            {
                Log.Schema("Finding anchor of root schema");
                if (context.BaseUri == null)
                {
                    throw new InvalidOperationException("BaseUri not set");
                }
                var baseDocument = JsonSchemaRegistry.Get(context.BaseUri.OriginalString);
                if (baseDocument?.Get <RecursiveAnchorKeyword>() != null)
                {
                    _resolvedRoot = context.RecursiveAnchor;
                }
            }

            if (Reference.IsLocalSchemaId())
            {
                Log.Schema("Reference recognized as anchor or local ID");
                Resolved = context.LocalRegistry.GetLocal(Reference);
                if (Resolved != null)
                {
                    return;
                }

                Log.Schema($"`{Reference}` is an unknown anchor");
            }

            var documentPath   = _resolvedRoot?.DocumentPath ?? context.BaseUri;
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? documentPath?.OriginalString : referenceParts[0];

            _resolvedFragment = referenceParts.Length > 1 ? JsonPointer.Parse(referenceParts[1]) : new JsonPointer();
            if (_resolvedRoot == null)
            {
                if (!string.IsNullOrWhiteSpace(address))
                {
                    if (!Uri.TryCreate(address, UriKind.Absolute, out _))
                    {
                        address = context.Local.Id + address;
                    }

                    if (documentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out _))
                    {
                        var uriFolder = documentPath.OriginalString.EndsWith("/") ? documentPath : documentPath.GetParentUri();
                        var absolute  = new Uri(uriFolder, address);
                        address = absolute.OriginalString;
                    }

                    _resolvedRoot = JsonSchemaRegistry.Get(address);
                }
                else
                {
                    _resolvedRoot = context.Root;
                }
            }

            if (_resolvedRoot == null)
            {
                Log.Schema("Could not resolve root of reference");
                return;
            }

            var wellKnown = JsonSchemaRegistry.GetWellKnown(Reference);

            if (wellKnown != null)
            {
                Log.Schema("Well known reference found");
                Resolved = wellKnown;
                return;
            }

            _ResolveLocalReference(_resolvedRoot?.DocumentPath ?? context.BaseUri !);
        }
示例#16
0
        private void _ResolveReference(SchemaValidationContext context)
        {
            Log.Schema($"Resolving `{Reference}`");

            if (Reference.IsLocalSchemaId())
            {
                Log.Schema("Reference recognized as anchor or local ID");
                Resolved = context.LocalRegistry.GetLocal(Reference);
                if (Resolved != null)
                {
                    return;
                }

                Log.Schema($"`{Reference}` is an unknown anchor");
            }

            var documentPath   = context.BaseUri;
            var referenceParts = Reference.Split(new[] { '#' }, StringSplitOptions.None);
            var address        = string.IsNullOrWhiteSpace(referenceParts[0]) ? documentPath?.OriginalString.Split('#')[0] : referenceParts[0];

            _resolvedFragment = referenceParts.Length > 1 ? JsonPointer.Parse(referenceParts[1]) : new JsonPointer();
            if (!string.IsNullOrWhiteSpace(address))
            {
                if (!Uri.TryCreate(address, UriKind.Absolute, out var absolute) &&
                    (JsonSchemaOptions.RefResolution == RefResolutionStrategy.ProcessSiblingId ||
                     context.Root.SupportedVersions == JsonSchemaVersion.Draft2019_09))
                {
                    address = context.Local.Id + address;
                }

                if (documentPath != null && !Uri.TryCreate(address, UriKind.Absolute, out absolute))
                {
                    var uriFolder = documentPath.OriginalString.EndsWith("/") ? documentPath : documentPath.GetParentUri();
                    absolute = new Uri(uriFolder, address);
                    address  = absolute.OriginalString;
                }

                _resolvedRoot = JsonSchemaRegistry.Get(address);
            }
            else
            {
                _resolvedRoot = context.Root;
            }

            if (_resolvedRoot == null)
            {
                Log.Schema("Could not resolve root of reference");
                return;
            }

            var wellKnown = JsonSchemaRegistry.GetWellKnown(Reference);

            if (wellKnown != null)
            {
                Log.Schema("Well known reference found");
                Resolved = wellKnown;
                return;
            }

            _ResolveLocalReference(_resolvedRoot?.DocumentPath ?? context.BaseUri !);
        }