Skip to content

oneOf validation failing with valid data #1596

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Droxx opened this issue May 15, 2023 · 3 comments
Open

oneOf validation failing with valid data #1596

Droxx opened this issue May 15, 2023 · 3 comments

Comments

@Droxx
Copy link

Droxx commented May 15, 2023

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.

@mindisk
Copy link

mindisk commented Nov 23, 2023

Are there any news regarding this issue?

From react-json-schema-forms V5 the enumName will be taken on a depreciation path (https://rjsf-team.github.io/react-jsonschema-form/docs/migration-guides/v5.x%20upgrade%20guide/#non-standard-enumnames-property).

The oneOf will be the new way of defining Enum values and names. Thus, this bug becomes blocker for future react-json-schema-forms upgrades.

@Droxx
Copy link
Author

Droxx commented Nov 27, 2023

Unfortunately due to this issue being a blocker, I had to migrate my software over to JsonSchema.net. So I have not investigated any further.

@mindisk
Copy link

mindisk commented Dec 1, 2023

A walkaround seem to be to use anyOf when defining constants

"anyOf": [
    {
       "const": "A",
        "title": "A"
    },
    {
       "const": "B",
       "title": "B"
    },
    {
       "const": "C",
       "title": "C"
    }

According to react-json-schema-forms documentation it is also a viable option and produces same result. At least it worked for me and the validation worked. Well, at least it seems so, for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants