Search code examples
jsonjsonschema

JSON Schema - unique pattern properties


I want to create a JSON Schema that allows properties with names that are arbitrary, but unique.

I have been trying to do this with patternProperties, but it seems to allow duplicate property names.

For example, the following schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "patternProperties": {
                "^.*$": {
                    "type": "string"
                }
            },
            "additionalProperties": false
}

Validates this JSON:

{
  "property1" : "value1",
  "property2" : "value2",
  "property1" : "value3"
}

But I want it to fail because the 1st and 3rd property have the same name. How can I do that?


Solution

  • IMHO...

    JSON Schema doesn't have any validation to detect duplicate properties in a JSON object.

    The JSON spec doesn't make any mention of duplicate properties so they are valid but not recommended.

    to check on duplicated names:

    void Main()
    {
        try
        {
            JsonSchema schema = JsonSchema.Parse(@"{
      '$schema': 'https://json-schema.org/draft/2020-12/schema',
        'type': 'object',
        'patternProperties': {
                    '^.*$': {
                        'type': 'string'
                    }
                },
                'additionalProperties': false
        }");
    
    
            JObject o = JObject.Parse("{\"property1\":\"value1\",\"property2\":\"value2\",\"property1\":\"value3\"}", new JsonLoadSettings
            {
                DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error
            });
    
            bool valid = o.IsValid(schema).Dump();
            // true
        }
        catch (JsonReaderException ex)
        {
            Console.Write($"Invalid json file, {ex.Message}.");
        }
    }
    
    

    the exception would be :

    [Invalid json file, Property with the name 'property1' already exists in the current JSON object. Path 'property1', line 1, position 55..]