如何用JsonSchema.Net验证JSON Schema是否符合官方标准
我一直在尝试用元Schema验证JSON Schema(检查该JSON是否符合JSON Schema标准),但碰了壁。我查了JsonSchema.Net的元Schema文档、选项文档,还有JSON Schema官方规范,但问题还是没解决。
我的场景是:开发一个接口,接收带Schema的JSON,之后要用这个Schema验证实体,但得先确保接收的Schema本身是合规的。
我写了下面这段代码,但不管输入啥测试内容,返回结果都是“有效”,完全没起到验证作用:
private void ValidateSchema(string schemaString) { var element = JsonNode.Parse(schemaString); var metaSchema = Json.Schema.MetaSchemas.Metadata202012; // 也试过Json.Schema.MetaSchemas.Draft202012; var options = new ValidationOptions { OutputFormat = OutputFormat.Detailed, ValidateMetaSchema = false // 也试过设为true }; var results = metaSchema.Validate(element, options); }
我用了这些测试输入,原本预期部分输入会返回“无效”:
{"f":"a"} {} {"required": ["prop1", "prop2", "prop3", "prop4", "prop5", "prop6"]} { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["prop1", "prop2", "prop3", "prop4", "prop5", "prop6"] }
问题出在这几个地方:
元Schema对象用错了
你用的MetaSchemas.Metadata202012是元数据容器,不是实际的元Schema实例。正确的应该用MetaSchemas.Draft202012,这才是Draft 2020-12版本的元Schema。没正确检查验证结果
你只调用了Validate方法,但没去判断results.IsValid这个属性——验证结果的有效性是通过这个布尔值来体现的,不是自动抛出错误。对
ValidateMetaSchema选项理解错了
这个选项是控制用Schema验证实体时,是否自动验证Schema本身,和你现在手动用元Schema验证Schema的场景无关,所以设为false没问题,但关键还是前面两点。
修正后的代码如下:
private bool ValidateSchema(string schemaString) { // 先检查输入的JSON格式是否合法 if (!JsonNode.TryParse(schemaString, out var element)) { return false; } // 使用对应版本的元Schema实例 var metaSchema = Json.Schema.MetaSchemas.Draft202012; var options = new ValidationOptions { OutputFormat = OutputFormat.Detailed, ValidateMetaSchema = false }; var results = metaSchema.Validate(element, options); // 核心:通过IsValid判断Schema是否合规 return results.IsValid; }
现在再测试你的输入,结果就符合预期了:
{"f":"a"}:无效,因为"f"不是JSON Schema的合法关键字{}:有效,空Schema是合法的(会允许任何实例通过验证){"required": ["prop1", ...]}:有效,required是合法关键字,数组格式也正确- 带
$schema的完整Schema:有效(如果要验证Draft 2020-12标准,需要把$schema的值改成https://json-schema.org/draft/2020-12/schema)
另外,如果要验证不同版本的Schema,要对应使用不同的元Schema:
- Draft 07:
MetaSchemas.Draft07 - Draft 2019-09:
MetaSchemas.Draft201909 - Draft 2020-12:
MetaSchemas.Draft202012
这样修改后,就能正确判断输入的Schema是否符合对应版本的JSON Schema标准了。
内容的提问来源于stack exchange,提问作者Lombas

