模式草案v7 if语句未详细告知错误

时间:2018-11-09 11:55:21

标签: json json.net jsonschema

我正在尝试使用JsonSchema中的if语句来验证必需的属性,但是并没有详细告知该属性错误。

验证已正确完成,但错误未指定属性以及验证失败。

它适用于对象根级别的必需属性,但是当我在对象内部指定必需属性时,它只是警告json不匹配,并指定了then或{{1} }模式的路径。

模式示例:

else

Json示例:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "name",
    "partners"
  ],
  "properties": {
    "partners": {
      "type": "array",
      "items": {
        "type": "object",
        "if": {
          "properties": {
            "juridical": {
              "type": "object"
            },
            "natural": {
              "type": "null"
            }
          }
        },
        "then": {
          "properties": {
            "juridical": {
              "required": [ "tradeName" ],
              "properties": {
                "tradeName": {
                  "type": "string"
                }
              }
            }
          }
        },
        "else": {
          "properties": {
            "natural": {
              "required": ["name"],
              "properties": {
                "name": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}

它应该警告第一位合伙人必须输入“姓名”({ "name": "Joao", "partners": [ { "juridical": null, "natural": { } }, { "juridical": { "tradeName": "" }, "natural": null } ] } ),而只能告诉我:Required properties are missing from object: name.

使用这样的简单模式,可以按预期工作:

模式示例:

JSON does not match schema from 'else'.

Json示例:

{
    "if": { "properties": { "power": { "minimum": 9000 } } },
    "then": { "required": [ "disbelief" ] },
    "else": { "required": [ "confidence" ] }
}

我正在使用JsonSchemaValidator.net来验证结果。

1 个答案:

答案 0 :(得分:0)

基本上,JSON文档是否根据JSON模式进行验证。这种逻辑贯穿于所有子模式和条件。

错误消息的内容取决于JSON Schema验证程序的特定实现。您使用的是来自特定提供商的。正如Relequestal指出的那样,除非提供者文档中有描述,否则您不能指望特定实现中的特定类型的错误消息处理。

如何向验证者的作者提出建议,以扩展if-then-else案例的信息,并为您的案例提供信息?

替代方法:据我了解,您的目标是使用此特定的验证器获取尽可能多的特定错误信息。就是这样,因此替代方案可能适合目标。由于JSON Schema本身是JSON文档,因此您可以考虑以下解决方法:以某种一致的方式在Schema中命名节点,并使用逻辑运算符(“ anyOf”(逻辑OR),“ allOf”(逻辑AND),“ oneOf” (逻辑XOR)),而不是 if-then-else

请注意:基于架构的验证器,如果“ allOf”,“ anyOf”,“ oneOf”应在所有架构中运行,直到满足逻辑条件。

  • “ allOf”-将始终检查JSON文档是否针对所有架构进行验证 (与)

  • “ anyOf”-将检查JSON文档是否至少针对1个模式进行验证 (或,因此某些验证器实现可能会在之后停止检查 第一个阳性结果,因为足以评估对照 “ anyOf”改为 true ),

  • “ oneOf”-将始终检查JSON文档是否针对以下内容进行了完全验证: 通过检查所有架构(XOR)来获得其中一种架构

(请参阅:https://json-schema.org/draft-07/json-schema-validation.html#rfc.section.6.7.1

因此,如果在上述情况下经过验证的实例与架构不匹配,验证器实现可能会在错误消息方面产生一些“误报”,因为它会列出所有架构所遇到的问题。它根本无法读懂我们的想法,无法猜测提供特定的JSON文档的含义,因此,所有这些都由我们来判断和决定。

许多解决方案之一可能是定义“司法”和“自然”的变体,然后按照您的期望,将它们逻辑地组合成模式:

  

司法不是对象(+相关约束),自然不是对象 司法不是对象,自然是对象   (+相关约束)。

替代模式(请注意“示例”部分包含一些测试JSON文档):

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "name",
    "partners"
  ],
  "properties": {
    "partners": {
      "type": "array",
      "items": {
        "type": "object",
        "anyOf" : [
          {"$ref" : "#/definitions/juridical-is-object-and-natural-is-null"},
          {"$ref" : "#/definitions/juridical-is-not-an-object-and-natural-is-an-object"}
        ],
        "required" : ["natural","juridical"]
      }
    }
  },
  "examples" : [
    {
      "name": "Joao",
      "partners": [
        {
          "juridical": null,
          "natural": {

          }
        },
        {
          "juridical": {
            "tradeName": ""
          },
          "natural": null
        }
      ]
    },
    {
      "name": "Joao",
      "partners": [
        {
          "juridical": null,
          "natural": {
            "name" : ""
          }
        },
        {
          "juridical": {
            "tradeName": ""
          },
          "natural": null
        }
      ]
    },
    {
      "name": "Joao",
      "partners": [
        {
          "juridical": null,
          "natural": {

          }
        },
        {
          "juridical": {
            "tradeName": ""
          },
          "natural": null
        },
        {
          "juridical" : [],
          "natural" : {}
        }
      ]
    }
  ],
  "definitions" : {
    "natural" : {
        "is-object" : {
          "type" : "object",
          "required": ["name"],
          "properties": {
            "name": {
              "type": "string"
            }
          }
        },
        "is-not-an-object" : {
          "not" : { "type" : "object" }
        },
    },
    "juridical" : {
      "is-object" : {
        "type" : "object",
        "required": ["tradeName"],
        "properties": {
          "name": {
            "type": "string"
          }
        }
      },
      "is-not-an-object" : {
        "not" : { "type" : "object" }
      },
    },
    "juridical-is-object-and-natural-is-null" : {
      "properties" : {
        "natural" : {"$ref" : "#/definitions/natural/is-not-an-object"},
        "juridical" : {"$ref" : "#/definitions/juridical/is-object"}
      },
    },
    "juridical-is-not-an-object-and-natural-is-an-object" : {
      "properties" : {
        "natural" : {"$ref" : "#/definitions/natural/is-object"},
        "juridical" : {"$ref" : "#/definitions/juridical/is-not-an-object"}
      }
    },
  }
}

注意:

“不是”:{ schema }错误消息可能使临时用户感到困惑,但它符合规范:https://json-schema.org/draft-07/json-schema-validation.html#rfc.section.6.7.4

更新

如注释中所述,您正在查看错误详细信息。鉴于所选工具在更复杂架构的if-then-else错误详细信息方面受到限制,您是否尝试使用其他关键字重塑架构以触发尽可能少的开销消息?

替代方案2

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "name",
    "partners"
  ],
  "properties": {
    "partners": {
      "type": "array",
      "items" : {
        "properties" : {
          "natural" : {
            "if" : { "type" : "object" },
            "then" : { "required" : ["name"] },
            "dependencies" : {
              "name" : {
                 "properties" : {
                  "name" : {"type" : "string"}
                 }
               }
            }
          },
          "juridical" : {
            "if" : { "type" : "object" },
            "then" : { "required" : ["tradeName"] },
            "dependencies" : {
              "tradeName" : {
                 "propertyNames" : {
                   "enum" : ["tradeName"]
                 },
                 "properties" : {
                  "tradeName" : {"type" : "string"}
                 }
               }
            }
          }
        },
        "anyOf" : [
          {"$ref" : "#/definitions/natural-is-null-juridical-is-an-object"},
          {"$ref" : "#/definitions/natural-is-an-object-juridical-is-null"}
        ]
      }
    }
  },
  "definitions" : {
    "natural-is-null-juridical-is-an-object" : {
        "properties" : {
            "natural" : { "type": "null"},
            "juridical" : { "type" : "object"}
        }
    },
    "natural-is-an-object-juridical-is-null" : {
        "properties" : {
            "natural" : { "type": "object"},
            "juridical" : { "type" : "null"}
        }
    },
  },
  "examples" : [
    {
      "name": "Joao",
      "partners": [
        {
          "juridical": null,
          "natural": {

          }
        },
        {
          "juridical": {
            "tradeName": "",
          },
          "natural": null
        },
        {
          "juridical" : {},
          "natural" : {}
        },
        {
          "juridical" : null,
          "natural" : null
        }
      ]
    },
  ]
}