NJsonSchema
NJsonSchema copied to clipboard
Array Items $ref stop working after 2 levels of nesting after v10.2.0
I recently upgraded an old project and some test cases broke. After debugging the test cases, they were failing due to JSONSchema.Item.Reference being null when it previously correctly resolved to a referenced schema. After trying a bunch of different versions, it looks like this broke in v10.2.0. Most likely cause by this commit, although I don't really understand why.
I put together this minimal repro to show the issue. For a schema with just 2 levels of nesting, it appears that the $ref is still correctly resolved. However, add 1 more level and suddenly NJsonSchema cannot resolve the reference. Other JsonSchema tools such as https://www.jsonschemavalidator.net/ seem to be able to resolve it without issue.
Here is the test case:
using Newtonsoft.Json.Linq;
using NJsonSchema;
using System.Threading.Tasks;
using Xunit;
namespace Validation.Core.Test
{
public class ArrayRefNotResolving_External_TestCase
{
[Fact]
public async Task Should_Fail_Validation_Working()
{
var testSchema = await JsonSchema.FromJsonAsync(workingSchemaJson);
var jObj = JObject.FromObject(
new
{
TopLevel = new
{
BottomLevel = new object[] {
new { ExampleRequiredField = "foo" },
new { ExampleRequiredField = 123 },
},
}
}
);
var results = testSchema.Validate(jObj);
//Should contain 1 error as ExampleRequiredField must be a string
Assert.True(results.Count == 1);
}
[Fact]
public async Task Should_Fail_Validation_Broken()
{
var testSchema = await JsonSchema.FromJsonAsync(brokenSchemaJson);
var jObj = JObject.FromObject(
new
{
TopLevel = new
{
MidLevel = new {
BottomLevel = new object[] {
new { ExampleRequiredField = "foo" },
new { ExampleRequiredField = 123 },
},
}
}
}
);
var results = testSchema.Validate(jObj);
//Should contain 1 error as ExampleRequiredField must be a string
Assert.True(results.Count == 1);
}
string workingSchemaJson = @"
{
""$schema"": ""http://json-schema.org/draft-07/schema"",
""$id"": ""http://example.com/example.json"",
""required"": [
""TopLevel""
],
""properties"": {
""TopLevel"": {
""$id"": ""#/properties/TopLevel"",
""type"": ""object"",
""required"": [
""BottomLevel""
],
""properties"": {
""BottomLevel"": {
""$id"": ""#/properties/BottomLevel"",
""type"": ""array"",
""items"": {
""$ref"": ""#/inputs/BottomLevel""
}
}
}
}
},
""inputs"": {
""BottomLevel"": {
""additionalProperties"": true,
""$id"": ""#/inputs/BottomLevel"",
""type"": ""object"",
""required"": [
""ExampleRequiredField""
],
""properties"": {
""ExampleRequiredField"": {
""$id"": ""#/properties/ExampleRequiredField"",
""name"": ""ExampleRequiredField"",
""type"": ""string""
}
}
}
}
}
";
string brokenSchemaJson = @"
{
""$schema"": ""http://json-schema.org/draft-07/schema"",
""$id"": ""http://example.com/example.json"",
""title"": ""Test Schema"",
""required"": [
""TopLevel""
],
""properties"": {
""TopLevel"": {
""$id"": ""#/properties/TopLevel"",
""type"": ""object"",
""required"": [
""MidLevel""
],
""properties"": {
""MidLevel"": {
""$ref"": ""#/inputs/MidLevel""
}
}
}
},
""inputs"": {
""BottomLevel"": {
""$id"": ""#/inputs/BottomLevel"",
""type"": ""object"",
""required"": [
""ExampleRequiredField""
],
""properties"": {
""ExampleRequiredField"": {
""$id"": ""#/properties/ExampleRequiredField"",
""name"": ""ExampleRequiredField"",
""type"": ""string""
}
}
},
""MidLevel"": {
""$id"": ""#/inputs/MidLevel"",
""type"": ""object"",
""required"": [
""BottomLevel""
],
""properties"": {
""BottomLevel"": {
""$id"": ""#/properties/BottomLevel"",
""type"": ""array"",
""items"": {
""$ref"": ""#/inputs/BottomLevel""
}
}
}
}
}
}
";
}
}
Searching around, a few others seem to have had this issue, although for them it is manifesting as an error like this: System.InvalidOperationException : The schema reference path '#/inputs/BottomLevel' has not been resolved.