/// <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 (Resolved == null) { _ResolveReference(context); if (Resolved == null) { throw new SchemaReferenceNotFoundException(context.RelativeLocation); } Log.Schema(() => "Reference found"); } var results = new SchemaValidationResults(Name, context); var newContext = new SchemaValidationContext(context) { BaseUri = _resolvedRoot?.DocumentPath, Instance = context.Instance, Root = _resolvedRoot ?? context.Root, BaseRelativeLocation = _resolvedFragment?.WithHash(), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name), }; var nestedResults = Resolved.Validate(newContext); results.IsValid = nestedResults.IsValid; results.NestedResults.Add(nestedResults); context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); return(results); }
/// <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) { var results = new SchemaValidationResults(Name, context); var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name), }; var nestedResults = Value.Validate(newContext); results.IsValid = !nestedResults.IsValid; if (nestedResults.IsValid) { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } if (!results.IsValid) { Log.Schema(() => "Subschema succeeded; inverting result"); results.ErrorMessage = ErrorTemplate; } if (context.Options.OutputFormat != SchemaValidationOutputFormat.Flag && context.Options.ShouldReportChildErrors(this, context)) { results.NestedResults = new List <SchemaValidationResults> { nestedResults } } ; return(results); }
/// <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) { var then = context.Local.Get <ThenKeyword>(); var @else = context.Local.Get <ElseKeyword>(); if (then != null || @else != null || context.ShouldTrackValidatedValues) { var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name), }; var ifResults = Value.Validate(newContext); context.Misc["ifKeywordValid"] = ifResults.IsValid; if (ifResults.IsValid) { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } } else { Log.Schema(() => "`then` and `else` keywords not present; skipping `if` validation"); } return(new SchemaValidationResults(Name, context)); }
/// <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) { var valid = false; var reportChildErrors = context.Options.ShouldReportChildErrors(this, context); var i = 0; var nestedResults = new List <SchemaValidationResults>(); var baseContext = new SchemaValidationContext(context); baseContext.EvaluatedPropertyNames.Clear(); baseContext.LocallyEvaluatedPropertyNames.Clear(); baseContext.LastEvaluatedIndex = -1; baseContext.LocalTierLastEvaluatedIndex = -1; foreach (var s in this) { var newContext = new SchemaValidationContext(baseContext) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name, i.ToString()), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name, i.ToString()), }; var localResults = s.Validate(newContext); valid |= localResults.IsValid; Log.Schema(() => $"`{Name}` {(valid ? "valid" : "invalid")} so far"); if (localResults.IsValid) { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { if (valid) { Log.Schema(() => "Subschema passed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } i++; } var resultsList = nestedResults.ToList(); var results = new SchemaValidationResults(Name, context) { NestedResults = resultsList, IsValid = valid }; if (!results.IsValid) { results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } return(results); }
/// <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) { var valid = true; var reportChildErrors = context.Options.ShouldReportChildErrors(this, context); var i = 0; var nestedResults = new List <SchemaValidationResults>(); var failedCount = 0; foreach (var s in this) { var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name, i.ToString()), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name, i.ToString()), }; var localResults = s.Validate(newContext); valid &= localResults.IsValid; Log.Schema(() => $"`{Name}` {(valid ? "valid" : "invalid")} so far"); if (!localResults.IsValid) { failedCount++; } else { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema(() => "Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } i++; } var results = new SchemaValidationResults(Name, context) { NestedResults = nestedResults, IsValid = valid }; if (!results.IsValid) { results.AdditionalInfo["failed"] = failedCount; results.AdditionalInfo["total"] = Count; results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } return(results); }
/// <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) { var reportChildErrors = context.Options.ShouldReportChildErrors(this, context); var i = 0; var nestedResults = new List <SchemaValidationResults>(); var validCount = 0; var contextCopy = new SchemaValidationContext(context); foreach (var s in this) { var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name, i.ToString()), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name, i.ToString()), }; var localResults = s.Validate(newContext); if (localResults.IsValid) { validCount++; contextCopy.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } Log.Schema(() => $"`{Name}` {validCount} items valid so far"); if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { if (validCount > 1) { Log.Schema(() => "More than one subschema succeeded; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } } var results = new SchemaValidationResults(Name, context) { IsValid = validCount == 1, NestedResults = nestedResults }; if (!results.IsValid) { Log.Schema(() => $"{validCount} subschemas passed validation; expected only one"); results.AdditionalInfo["passed"] = validCount; results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } else { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(contextCopy); } return(results); }
/// <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.RecursiveRefValidatedLocations == null) { context.RecursiveRefValidatedLocations = new List <JsonPointer>(); } if (context.RecursiveRefValidatedLocations.Any(l => Equals(l, context.InstanceLocation))) { return new SchemaValidationResults(Name, context) { RecursionDetected = true, AnnotationValue = "Detected recursive loop. Processing halted on this branch." } } ; if (Resolved == null) { _ResolveReference(context); if (Resolved == null) { throw new SchemaReferenceNotFoundException(context.RelativeLocation); } Log.Schema(() => "Reference found"); } var results = new SchemaValidationResults(Name, context); var newContext = new SchemaValidationContext(context) { BaseUri = _resolvedRoot !.DocumentPath, Root = _resolvedRoot ?? context.Root, BaseRelativeLocation = _resolvedFragment !.WithHash(), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name), }; context.RecursiveRefValidatedLocations.Add(context.InstanceLocation); var nestedResults = Resolved.Validate(newContext); context.RecursiveRefValidatedLocations.Remove(context.InstanceLocation); results.IsValid = nestedResults.IsValid; results.NestedResults.Add(nestedResults); context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); return(results); }
/// <summary> /// Provides the validation logic for this dependency. /// </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) { var results = new SchemaValidationResults(PropertyName, context) { Keyword = $"{context.Misc["dependencyParent"]}/{PropertyName}" }; if (context.Instance.Type != JsonValueType.Object) { Log.Schema(() => "Instance not an object; not applicable"); return(results); } if (!context.Instance.Object.ContainsKey(PropertyName)) { Log.Schema(() => $"Property {PropertyName} not found; not applicable"); return(results); } var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(PropertyName), RelativeLocation = context.RelativeLocation.CloneAndAppend(PropertyName), }; var nestedResult = _schema.Validate(newContext); results.NestedResults = new List <SchemaValidationResults> { nestedResult }; if (!nestedResult.IsValid) { Log.Schema(() => $"Property {PropertyName} found, but subschema failed"); results.IsValid = false; results.ErrorMessage = ErrorTemplate; } else { if (context.ShouldTrackValidatedValues) { newContext.LocallyEvaluatedPropertyNames.Add(PropertyName); } context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } return(results); }
/// <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.Misc.TryGetValue("ifKeywordValid", out var ifKeywordValidStore)) { Log.Schema(() => "`if` keyword not present; not applicable"); return(new SchemaValidationResults(Name, context)); } var ifKeywordValid = (bool)ifKeywordValidStore; if (!ifKeywordValid) { Log.Schema(() => "`if` subschema failed; not applicable"); return(new SchemaValidationResults(Name, context)); } var results = new SchemaValidationResults(Name, context); var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name), }; var thenResults = Value.Validate(newContext); if (thenResults.IsValid) { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } else { Log.Schema(() => "`if` subschema succeeded, but `then` subschema failed"); results.IsValid = false; results.Keyword = Name; results.ErrorMessage = ErrorTemplate; if (context.Options.ShouldReportChildErrors(this, context)) { results.NestedResults.Add(thenResults); } } return(results); }
/// <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.Instance.Type != JsonValueType.Array) { Log.Schema("Instance not an array; not applicable"); return(new SchemaValidationResults(Name, context)); } var nestedResults = new List <SchemaValidationResults>(); var array = context.Instance.Array; var results = new SchemaValidationResults(Name, context); var valid = true; var reportChildErrors = JsonSchemaOptions.ShouldReportChildErrors(this, context); var startIndex = context.LastEvaluatedIndex + 1; Log.Schema(startIndex == 0 ? "No indices have been evaluated; process all" : $"Indices up to {context.LastEvaluatedIndex} have been evaluated; skipping these"); if (startIndex < array.Count) { if (Value == JsonSchema.False) { Log.Schema("Subschema is `false`; all instances invalid"); results.IsValid = false; results.Keyword = Name; results.ErrorMessage = ErrorTemplate; return(results); } var eligibleItems = array.Skip(startIndex); var index = startIndex; foreach (var item in eligibleItems) { var baseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name); var relativeLocation = context.RelativeLocation.CloneAndAppend(Name); var newContext = new SchemaValidationContext(context) { Instance = item, BaseRelativeLocation = baseRelativeLocation, RelativeLocation = relativeLocation, InstanceLocation = context.InstanceLocation.CloneAndAppend(index.ToString()), }; var localResults = Value.Validate(newContext); valid &= localResults.IsValid; if (valid) { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } index++; if (JsonSchemaOptions.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema("Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } } } else { Log.Schema("All items have been validated"); } results.NestedResults = nestedResults; results.IsValid = valid; results.Keyword = Name; if (!valid) { results.ErrorMessage = ErrorTemplate; } return(results); }
/// <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.Instance.Type != JsonValueType.Array) { return(new SchemaValidationResults(Name, context)); } var itemsKeyword = context.Local.Get <ItemsKeyword?>(); if (itemsKeyword == null || !itemsKeyword.IsArray) { return(new SchemaValidationResults(Name, context)); } var nestedResults = new List <SchemaValidationResults>(); var array = context.Instance.Array; var results = new SchemaValidationResults(Name, context); var valid = true; var reportChildErrors = context.Options.ShouldReportChildErrors(this, context); var startIndex = context.LocalTierLastEvaluatedIndex + 1; var failedIndices = new JsonArray(); Log.Schema(() => startIndex == 0 ? "No indices have been evaluated; process all" : $"Indices up to {context.LastEvaluatedIndex} have been evaluated; skipping these"); if (startIndex < array.Count) { if (Value == JsonSchema.False) { Log.Schema(() => $"Subschema is `false`; all instances after index {startIndex} are invalid"); results.IsValid = false; results.Keyword = Name; results.AdditionalInfo["indices"] = Enumerable.Range(startIndex, array.Count - startIndex).ToJson(); results.ErrorMessage = ErrorTemplate_False.ResolveTokens(results.AdditionalInfo); return(results); } var eligibleItems = array.Skip(startIndex); var index = startIndex; foreach (var item in eligibleItems) { var baseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name); var relativeLocation = context.RelativeLocation.CloneAndAppend(Name); var newContext = new SchemaValidationContext(context) { Instance = item, BaseRelativeLocation = baseRelativeLocation, RelativeLocation = relativeLocation, InstanceLocation = context.InstanceLocation.CloneAndAppend(index.ToString()), }; var localResults = Value.Validate(newContext); if (!localResults.IsValid) { failedIndices.Add(index); } else if (context.ShouldTrackValidatedValues) { newContext.LocallyValidatedIndices.Add(index); } valid &= localResults.IsValid; context.LastEvaluatedIndex = Math.Max(context.LastEvaluatedIndex, index); context.LocalTierLastEvaluatedIndex = Math.Max(context.LastEvaluatedIndex, index); context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); index++; if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema(() => "Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } } } else { Log.Schema(() => "All items have been validated"); } results.NestedResults = nestedResults; results.IsValid = valid; results.Keyword = Name; if (!valid) { results.AdditionalInfo["indices"] = failedIndices; results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } return(results); }
/// <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) { var results = new SchemaValidationResults(Name, context); if (context.Instance.Type != JsonValueType.Object) { Log.Schema("Instance not an object; not applicable"); return(results); } var nestedResults = new List <SchemaValidationResults>(); var obj = context.Instance.Object; var reportChildErrors = JsonSchemaOptions.ShouldReportChildErrors(this, context); var valid = true; foreach (var patternProperty in this) { var pattern = new Regex(patternProperty.Key); var localSchema = patternProperty.Value; var matches = obj.Keys.Where(k => pattern.IsMatch(k)); if (matches.Any()) { Log.Schema($"Properties {matches.ToJson()} are matches for regular expression \"{pattern}\""); var baseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name, patternProperty.Key); var relativeLocation = context.RelativeLocation.CloneAndAppend(Name, patternProperty.Key); foreach (var match in matches) { context.EvaluatedPropertyNames.Add(match); context.LocallyEvaluatedPropertyNames.Add(match); var newContext = new SchemaValidationContext(context) { Instance = obj[match], BaseRelativeLocation = baseRelativeLocation, RelativeLocation = relativeLocation, InstanceLocation = context.InstanceLocation.CloneAndAppend(match), }; var localResults = localSchema.Validate(newContext); valid &= localResults.IsValid; if (valid) { context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } if (JsonSchemaOptions.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema("Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } } } else { Log.Schema($"No properties found that match regular expression \"{pattern}\""); } } results.IsValid = valid; if (reportChildErrors) { results.NestedResults = nestedResults; } if (!results.IsValid) { results.ErrorMessage = ErrorTemplate; } return(results); }
/// <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) { var results = new SchemaValidationResults(Name, context); if (context.Instance.Type != JsonValueType.Array) { Log.Schema("Instance not an array; not applicable"); return(results); } var reportChildErrors = JsonSchemaOptions.ShouldReportChildErrors(this, context); var nestedResults = new List <SchemaValidationResults>(); var array = context.Instance.Array; var failedIndices = new JsonArray(); if (IsArray) { // have array of schemata: validate in sequence Log.Schema("items is an array; process elements index-aligned"); var i = 0; while (i < array.Count && i < Count) { var newContext = new SchemaValidationContext(context) { Instance = array[i], BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name, i.ToString()), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name, i.ToString()), InstanceLocation = context.InstanceLocation.CloneAndAppend(i.ToString()), }; var localResults = this[i].Validate(newContext); if (JsonSchemaOptions.OutputFormat == SchemaValidationOutputFormat.Flag && !localResults.IsValid) { Log.Schema("Subschema failed; halting validation early"); results.IsValid = false; break; } if (!localResults.IsValid) { failedIndices.Add(i); } else { context.LocallyValidatedIndices.Add(i); } if (reportChildErrors) { nestedResults.Add(this[i].Validate(newContext)); } context.LastEvaluatedIndex = Math.Max(context.LastEvaluatedIndex, i); context.LocalTierLastEvaluatedIndex = Math.Max(context.LocalTierLastEvaluatedIndex, i); context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); i++; } results.IsValid = nestedResults.All(r => r.IsValid); results.NestedResults = nestedResults; } else { Log.Schema("items is an single subschema; process all elements"); // have single schema: validate all against this var baseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name); var relativeLocation = context.RelativeLocation.CloneAndAppend(Name); var valid = true; var i = 0; foreach (var jv in array) { var newContext = new SchemaValidationContext(context) { Instance = jv, BaseRelativeLocation = baseRelativeLocation, RelativeLocation = relativeLocation, InstanceLocation = context.InstanceLocation.CloneAndAppend(i.ToString()), }; var localResults = this[0].Validate(newContext); valid &= localResults.IsValid; if (!localResults.IsValid) { failedIndices.Add(i); } else { context.LocallyValidatedIndices.Add(i); } context.LastEvaluatedIndex = Math.Max(context.LastEvaluatedIndex, i); context.LocalTierLastEvaluatedIndex = Math.Max(context.LocalTierLastEvaluatedIndex, i); context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); if (JsonSchemaOptions.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema("Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } i++; } results.IsValid = valid; results.NestedResults = nestedResults; } if (!results.IsValid) { results.AdditionalInfo["indices"] = failedIndices; results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } return(results); }
/// <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.Instance.Type != JsonValueType.Object) { Log.Schema(() => "Instance not an object; not applicable"); return(new SchemaValidationResults(Name, context)); } var obj = context.Instance.Object; var results = new SchemaValidationResults(Name, context); var toEvaluate = obj.Where(kvp => !context.LocallyEvaluatedPropertyNames.Contains(kvp.Key)) !.ToJson(); if (toEvaluate.Count == 0) { Log.Schema(() => "All properties have been evaluated"); return(results); } Log.Schema(() => context.LocallyEvaluatedPropertyNames.Count == 0 ? "No properties have been evaluated; process all" : $"Properties {context.LocallyEvaluatedPropertyNames.ToJson()} have been evaluated; skipping these"); if (Value == JsonSchema.False && toEvaluate.Any()) { Log.Schema(() => "Subschema is `false`; all instances invalid"); results.IsValid = false; results.Keyword = Name; results.AdditionalInfo["properties"] = toEvaluate.Keys.ToJson(); results.ErrorMessage = ErrorTemplate_False.ResolveTokens(results.AdditionalInfo); return(results); } var valid = true; var reportChildErrors = context.Options.ShouldReportChildErrors(this, context); var nestedResults = new List <SchemaValidationResults>(); var failedProperties = new JsonArray(); foreach (var kvp in toEvaluate) { if (context.ShouldTrackValidatedValues) { context.EvaluatedPropertyNames.Add(kvp.Key); } context.LocallyEvaluatedPropertyNames.Add(kvp.Key); var newContext = new SchemaValidationContext(context) { Instance = kvp.Value, BaseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name), RelativeLocation = context.RelativeLocation.CloneAndAppend(Name), InstanceLocation = context.InstanceLocation.CloneAndAppend(kvp.Key), }; var localResults = Value.Validate(newContext); if (!localResults.IsValid) { failedProperties.Add(kvp.Key); } else { if (context.ShouldTrackValidatedValues) { newContext.LocallyEvaluatedPropertyNames.Add(kvp.Key); } context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); } valid &= localResults.IsValid; if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema(() => "Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } } results.NestedResults = nestedResults; if (!valid || nestedResults.Any(r => !r.IsValid)) { results.IsValid = false; results.Keyword = Name; results.AdditionalInfo["properties"] = failedProperties; results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } return(results); }
/// <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) { var baseRelativeLocation = context.BaseRelativeLocation?.CloneAndAppend(Name); var relativeLocation = context.RelativeLocation.CloneAndAppend(Name); var valid = true; var reportChildErrors = context.Options.ShouldReportChildErrors(this, context); var nestedResults = new List <SchemaValidationResults>(); var failedCount = 0; foreach (var d in this) { var newContext = new SchemaValidationContext(context) { BaseRelativeLocation = baseRelativeLocation, RelativeLocation = relativeLocation, Misc = { ["dependencyParent"] = Name } }; var localResults = d.Validate(newContext); valid &= localResults.IsValid; if (!localResults.IsValid) { failedCount++; } else if (context.ShouldTrackValidatedValues) { newContext.LocallyEvaluatedPropertyNames.Add(d.PropertyName); } context.UpdateEvaluatedPropertiesAndItemsFromSubschemaValidation(newContext); if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { if (!valid) { Log.Schema(() => "Subschema failed; halting validation early"); break; } } else if (reportChildErrors) { nestedResults.Add(localResults); } } var results = new SchemaValidationResults(Name, context) { IsValid = valid }; if (context.Options.OutputFormat == SchemaValidationOutputFormat.Flag) { results.NestedResults = nestedResults; } else if (!results.IsValid) { results.AdditionalInfo["failed"] = failedCount; results.AdditionalInfo["total"] = Count; results.ErrorMessage = ErrorTemplate.ResolveTokens(results.AdditionalInfo); } return(results); }