C# 使用Json.Net模式验证和多级子模式引用

C# 使用Json.Net模式验证和多级子模式引用,c#,json.net,jsonschema,C#,Json.net,Jsonschema,我有一个Json模式,它有一个相对文件引用,如下所示: { "$id": "TestPacket", "title": "TestPacket", "type": "object", "properties": { "Header": { "$ref": "../../TestSchema/Test/TestHeader.json#" }, "Body": { "$ref": "../../TestSchema/Test/Test.json

我有一个Json模式,它有一个相对文件引用,如下所示:

{
"$id": "TestPacket",
"title": "TestPacket",
"type": "object",
"properties": {
    "Header": {
        "$ref": "../../TestSchema/Test/TestHeader.json#"
    },
    "Body": {
        "$ref": "../../TestSchema/Test/Test.json#"
    }
}
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"));
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模式验证时,问题就出现了。目前,我们正在将json嵌入程序集中,并使用JSchemaPreloaderSolver来解析它们,如下所示:

{
"$id": "TestPacket",
"title": "TestPacket",
"type": "object",
"properties": {
    "Header": {
        "$ref": "../../TestSchema/Test/TestHeader.json#"
    },
    "Body": {
        "$ref": "../../TestSchema/Test/Test.json#"
    }
}
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中,它也会通过

我在将BaseUri设置为根文件夹的情况下使用JSchemaReaderSettings时遇到了类似的问题。我最终意识到它将成功解析第一个引用,但在尝试解析第二个引用时,BaseUri将被移动到Test.Json位置。 我怀疑这是问题所在,因为Add()只是将引用字符串和流添加到字典中进行查找。在我看来,只要解析器URI和模式$ref URI匹配,它们中的内容就不重要


我的问题总是发生在我试图解析自身被引用的模式的引用时。有什么建议吗?

好的,我知道我做错了什么。根据:

$id属性是一个URI,有两个用途: 1) 它为模式声明一个唯一标识符。 2) 它声明了一个基本URI,$ref URI是根据该URI解析的

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


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

您是否不愿意尝试使用不同的$id和$ref引用URI?如果是这样,我帮不了你。我愿意尝试任何事情。您的建议是什么?可以肯定的是,在您的示例代码中,在添加新的解析器模式时,似乎缺少了一个双引号。。。