Skip to content

oneOf validation failing with valid data #1596

@Droxx

Description

@Droxx

I have discovered an interesting problem in NJsonSchema validation.

For some context, I am using NJsonSchema to validate data coming in from a json-forms implementation.
I won't include my exact schema and data here, but I wrote a unit test and managed to replicate this behavior with some test data, please see below:

Schema:

{
  "type": "object",
  "required": [
    "USER"
  ],
  "properties": {
    "$schema": {
      "type": "string"
    },
    "USER": {
      "type": "string"
    },
    "PASSWORD": {
      "type": "string"
    },
    "SINGLE_CHOICE": {
      "type": "string",
      "title": "Single choice",
      "description": "Some description",
      "oneOf": [
        {
          "const": "Yes",
          "title": "Yes"
        },
        {
          "const": "No",
          "title": "No"
        }
      ]
    },
    "MULTI_CHOICE": {
      "type": "array",
      "title": "Multi choice",
      "description": "Some description",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "oneOf": [
          {
            "const": "A",
            "title": "A"
          },
          {
            "const": "B",
            "title": "B"
          },
          {
            "const": "C",
            "title": "C"
          }
        ]
      }
    }
  },
  "additionalProperties": false
}

Data:

{
  "$schema": "./schema.json",
  "USER": "value",
  "SINGLE_CHOICE": "Yes",
  "MULTI_CHOICE": ["A", "C"] 
}

Using NJsonSchema fails to validate this data, specifically on the oneOf properties. Each time I get an error back from the validator saying that the provided data is not oneOf the available options. Json validation failed: NotOneOf: #/SINGLE_CHOICE
I have run the above example through NewtonSoft's own validator, and it passes validation. However, the nuget package (10.9.0), fails.

I stepped through the validation code in order to try diagnosing this and I noticed that the oneOf options in the Schema object are stored in the ExtensionData property, which is never checked during validation, so every provided option matches, this, then causes a failure in the oneOf validator, since it's not getting any fails (the oneOf validation code returns valid only if there are n-1 errors, where n is the number of oneOf options)

        private void ValidateOneOf(JToken token, JsonSchema schema, string propertyName, string propertyPath, List<ValidationError> errors)
        {
            if (schema._oneOf.Count > 0)
            {
                var propertyErrors = schema._oneOf.ToDictionary(s => s, s => Validate(token, s)); <--- In my example, validate always has 0 errors
                if (propertyErrors.Count(s => s.Value.Count == 0) != 1)
                {
                    errors.Add(new ChildSchemaValidationError(ValidationErrorKind.NotOneOf, propertyName, propertyPath, propertyErrors, token, schema));
                }
            }
        }

I believe this is a bug in the nuget package, since I have validated this data online using newtonsoft.
JsonSchema.Net also correctly validates this data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions