代码之家  ›  专栏  ›  技术社区  ›  Ceilingfish

JSON问题。net anyOf架构验证

  •  1
  • Ceilingfish  · 技术社区  · 8 年前

    我正在使用 JSON.Net schema validation package 我遇到了一个非常奇怪的问题。我已经查到了这个问题 anyOf anyObject 定义如下:

    {
      "$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"]
      }
    }
    

    如果我删除 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/

    1 回复  |  直到 8 年前
        1
  •  1
  •   Relequestual    8 年前

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

    为了进行调试,我按照验证过程完成了模式,设置 $ref then else false 。。。当我到达 computedBody ,我将其更改为以下内容。。。

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

    验证结果仍然是肯定的,这应该是不可能的。我证明它达到了 计算体 通过将子模式设置为 错误 看到验证结果是否定的。

    (the oneOf 包装子模式 计算体 不需要。 if 在架构级别有效)。