JSON.net 任何架构验证时出现问题



我正在使用 JSON.Net 架构验证包,遇到了一个非常奇怪的问题。我已经将该问题追踪到在下面的anyObject定义中使用anyOf

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/schemas/example/1.0/schema.json",
  "anyOf": [
    {
      "$ref": "#/definitions/anyObject"
    }
  ],
  "definitions": {
    "anyObject": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        }
      },
      "required": [
        "type"
      ],
      "anyOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "typeA"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/typeA"
          },
          "else": false
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "typeB"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/typeB"
          },
          "else": false
        }
      ]
    },
    "bodyDefinition": {
      "oneOf": [
        {
          "if": {
            "properties": {
              "$computed": {
                "type": "string"
              }
            },
            "required": [
              "$computed"
            ]
          },
          "then": {
            "$ref": "#/definitions/computedBody"
          },
          "else": {
            "$ref": "#/definitions/wildcardBody"
          }
        },
        {
            "type": "string"
        }
      ]
    },
    "wildcardBody": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/bodyDefinition"
      }
    },
    "firstComputedValue": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "$computed": {
          "const": "first"
        },
        "values": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/bodyDefinition"
          }
        }
      },
      "required": [
        "$computed",
        "values"
      ]
    },
    "computedBody": {
      "oneOf": [
        {
          "if": {
            "properties": {
              "$computed": {
                "const": "first"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/firstComputedValue"
          },
          "else": false
        }
      ]
    },
    "typeA": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "const": "typeA"
        },
        "body": {
          "$ref": "#/definitions/bodyDefinition"
        }
      },
      "required": [
        "type"
      ]
    },
    "typeB": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "const": "typeB"
        },
        "body": {
          "$ref": "#/definitions/bodyDefinition"
        }
      },
      "required": [
        "type"
      ]
    }
  }
}

当我测试这个 json 时:

{
  "type": "typeB",
  "body":{
     "$computed":"first",
     "values":[]
  }
}

它应该被标记为无效,因为values至少需要一个值。但是它是有效的。以下 JSON 应被视为有效,并且上述架构确实正确断言:

{
  "type": "typeB",
  "body":{
     "$computed":"first",
     "values":["foo"]
  }
}

如果我从anyObject定义中删除typeA,则验证将正确执行。下面是正确验证的架构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/schemas/example/1.0/schema.json",
  "anyOf": [
    {
      "$ref": "#/definitions/anyObject"
    }
  ],
  "definitions": {
    "anyObject": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        }
      },
      "required": [
        "type"
      ],
      "anyOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "typeB"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/typeB"
          },
          "else": false
        }
      ]
    },
    "bodyDefinition": {
      "oneOf": [
        {
          "if": {
            "properties": {
              "$computed": {
                "type": "string"
              }
            },
            "required": [
              "$computed"
            ]
          },
          "then": {
            "$ref": "#/definitions/computedBody"
          },
          "else": {
            "$ref": "#/definitions/wildcardBody"
          }
        },
        {
            "type": "string"
        }
      ]
    },
    "wildcardBody": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/bodyDefinition"
      }
    },
    "firstComputedValue": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "$computed": {
          "const": "first"
        },
        "values": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/bodyDefinition"
          }
        }
      },
      "required": [
        "$computed",
        "values"
      ]
    },
    "computedBody": {
      "oneOf": [
        {
          "if": {
            "properties": {
              "$computed": {
                "const": "first"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/firstComputedValue"
          },
          "else": false
        }
      ]
    },
    "typeA": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "const": "typeA"
        },
        "body": {
          "$ref": "#/definitions/bodyDefinition"
        }
      },
      "required": [
        "type"
      ]
    },
    "typeB": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "const": "typeB"
        },
        "body": {
          "$ref": "#/definitions/bodyDefinition"
        }
      },
      "required": [
        "type"
      ]
    }
  }
}

任何人都可以查看此定义是否存在问题,或者这是 JSON.Net 架构包的问题?

此测试是针对架构验证器的在线版本完成的 https://www.jsonschemavalidator.net/

我认为这是一个错误。我会和图书馆的作者谈谈!

为了调试,我遵循了整个架构的验证过程,将$refthenelse设置为false...当我到达computedBody时,我将其更改为以下内容...

"computedBody": {
      "if": {
        "properties": {
          "$computed": {
            "const": "first"
          }
        }
      },
      "then": false,
      "else": false
    }

验证仍然返回正值,这应该是不可能的。我通过将子架构设置为 false 并看到验证返回负面结果来证明它达到了computedBody

(不需要包装computedBody子架构的oneOfif在架构级别有效即可(。

最新更新