将Json.Net架构验证与多个级别的子架构引用一起使用

时间:2019-05-07 21:03:59

标签: c# json.net jsonschema

我有一个具有相对文件引用的Json Schema,如下所示:

{
"$id": "TestPacket",
"title": "TestPacket",
"type": "object",
"properties": {
    "Header": {
        "$ref": "../../TestSchema/Test/TestHeader.json#"
    },
    "Body": {
        "$ref": "../../TestSchema/Test/Test.json#"
    }
}

Test.json也有一个相对文件引用:

{
"$id": "Test",
"title": "Test",
"type": "object",
"properties": {
    "Group": {
        "title": "Group",
        "type": "string"
    },
    "Child": {
        "$ref": "../../TestSchema/Test/Child.json#"
    }
},
"required": [
    "Version",
    "Group"
]}

Quicktype和XMLSpy都能够成功解析此代码(我尝试了除“ ../../folder/folder”模式之外的许多其他方法,这对于我们要使用的方法最有效)。

当我尝试使用Json.Net Schema Validation时出现了我的问题。当前,我们将json嵌入到程序集中,并使用JSchemaPreloadedResolver对其进行解析,如下所示:

JSchemaPreloadedResolver resolver = new JSchemaPreloadedResolver();
resolver.Add(new Uri(TestSchema/Test/Test.json", UriKind.RelativeOrAbsolute, assembly.GetManifestResourceStream("SchemaTests.TestSchema.Test.Test.json"));
resolver.Add(new Uri(TestSchema/Test/Child.json", UriKind.RelativeOrAbsolute, assembly.GetManifestResourceStream("SchemaTests.TestSchema.Test.Child.json"));
resolver.Add(new Uri(TestSchema/Test/TestPacket.json", UriKind.RelativeOrAbsolute, assembly.GetManifestResourceStream("SchemaTests.TestSchema.Test.TestPacket.json"));    resolver.Add(new Uri(TestSchema/Test/TestHeader.json", UriKind.RelativeOrAbsolute, assembly.GetManifestResourceStream("SchemaTests.TestSchema.Test.TestHeader.json"));

当我使用此解析器从JsonReader加载JSchema时,只要没有第二个子模式引用,它就可以很好地工作。实际上,在此示例中,TestHeader.json进行了解析,但是当涉及到Test.json时,它将失败。如果我将Child作为定义而不是相对引用包含在Test.json中,则它也会通过。

在将JSchemaReaderSettings与BaseUri设置为根文件夹时,我遇到了类似的问题。我最终意识到,它可以成功解析第一个引用,但是当尝试解析第二个引用时,BaseUri将被移至Test.Json位置。 我怀疑这是问题所在,因为Add()只是将参考字符串和流添加到字典中以进行查找。在我看来,只要解析器URI和架构$ ref URI匹配,就无关紧要。

当我尝试解析本身被引用的架构的引用时,总是会出现我的问题。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

好的,我发现我做错了什么。根据{{​​3}}:

  

$ id属性是一个有两个目的的URI:   1)声明架构的唯一标识符。   2)它声明一个基本URI,可用来解析$ ref URI。

因为我的子模式(Test.json)中有一个$ id属性,所以它在解析时将基本URI更改为该位置。这导致子模式中的下一个引用不正确。

当我在除顶级架构之外的所有架构中删除$ id属性时,所有架构现在都可以正确解析。

相关问题