如何使用JSON.net引用外部文件?

时间:2014-07-15 21:27:21

标签: c# json json.net jsonschema

当JSON.net尝试读取我的JSON架构(return JsonSchema.Read(new JsonTextReader(reader));)时,我遇到的错误是:

2014-07-15 15:33:42.7011 [Fatal] Newtonsoft.Json.JsonException: Could not resolve schema reference 'data-result.json'.
   at Newtonsoft.Json.Schema.JsonSchemaBuilder.ResolveReferences(JsonSchema schema) in c:\Development\Releases\Json\Work
ing\Newtonsoft.Json\Src\Newtonsoft.Json\Schema\JsonSchemaBuilder.cs:line 139
   at Newtonsoft.Json.Schema.JsonSchemaBuilder.ResolveReferences(JsonSchema schema) in c:\Development\Releases\Json\Work
ing\Newtonsoft.Json\Src\Newtonsoft.Json\Schema\JsonSchemaBuilder.cs:line 179
   at Newtonsoft.Json.Schema.JsonSchemaBuilder.Read(JsonReader reader) in c:\Development\Releases\Json\Working\Newtonsof
t.Json\Src\Newtonsoft.Json\Schema\JsonSchemaBuilder.cs:line 85
   at Newtonsoft.Json.Schema.JsonSchema.Read(JsonReader reader, JsonSchemaResolver resolver) in c:\Development\Releases\
Json\Working\Newtonsoft.Json\Src\Newtonsoft.Json\Schema\JsonSchema.cs:line 280
   at Newtonsoft.Json.Schema.JsonSchema.Read(JsonReader reader) in c:\Development\Releases\Json\Working\Newtonsoft.Json\
Src\Newtonsoft.Json\Schema\JsonSchema.cs:line 266
   at ThinkBinary.SchemaToPoco.Core.JsonSchemaToCodeUnit.LoadSchema(String file) in c:\Users\SLiu\Projects\json-schema-t
o-poco\Source\ThinkBinary.SchemaToPoco.Core\JsonSchemaToCodeUnit.cs:line 70
   at ThinkBinary.SchemaToPoco.Core.JsonSchemaToCodeUnit..ctor(String schemaDocument, String requestedNamespace) in c:\U
sers\SLiu\Projects\json-schema-to-poco\Source\ThinkBinary.SchemaToPoco.Core\JsonSchemaToCodeUnit.cs:line 19
   at ThinkBinary.SchemaToPoco.Console.Program.Main(String[] args) in c:\Users\SLiu\Projects\json-schema-to-poco\Source\
ThinkBinary.SchemaToPoco.Console\Program.cs:line 38

我的JSON架构:

{
  "$schema": "http://json-schema.org/draft-03/schema#",
  "title": "DataSet",
  "description": "A result set and description of measures and values",
  "type": "object",
  "properties": {
    "results": {
      "$ref": "data-result.json"
    },
    "dimensions": {
      "type": "array",
      "description": "An array of data dimensions included in a result set",
      "items": {
        "$ref": "data-dimension.json"
      },
      "uniqueItems": true
    },
    "measure": {
      "$ref": "data-measure.json",
      "description": "single measure represented in this data set."
    }
  },
}

我的问题是我有这个JSON模式,引用了外部文件data-result.json,但JSON.net还不知道它存在。对此有什么解决方法吗?我的一个想法是浏览模式,如果有任何对外部文件的引用,则解析具有公共JsonSchemaResolver的模式。我必须在适当的时候添加ID,因为看起来$ref喜欢通过ID进行匹配,即使在json-schema.org上,也有$ref与{一起使用}的明显示例{3}}。我想知道JSON.net是否有更好的方式支持引用外部模式。

源代码托管在file names上,如果有帮助的话。我已经测试删除了$ref字段,并且编译成功。

3 个答案:

答案 0 :(得分:1)

Json.NET Schema 大大改进了对解析外部参考的支持。

在此处阅读更多内容:http://www.newtonsoft.com/jsonschema/help/html/LoadingSchemas.htm

答案 1 :(得分:1)

  

我的一个想法是浏览模式,如果有任何对外部文件的引用,要解析那些具有公共JsonSchemaResolver的文件

是的,您需要知道架构所依赖的架构,首先解析它们并将它们添加到JsonSchemaResolver。模式将使用其ID进行解析。

这是一个例子(使用draft-03语法):

var baseSchema = JsonSchema.Parse(@"
{
  ""$schema"": ""http://json-schema.org/draft-03/schema#"",
  ""id"": ""http://mycompany/base-schema#"",
  ""type"": ""object"",

  ""properties"": {
    ""firstName"": { ""type"": ""string"", ""required"": true}
  }
}
");

var resolver = new JsonSchemaResolver
    {
        LoadedSchemas = {baseSchema}
    };

var derivedSchema = JsonSchema.Parse(@"
{
  ""$schema"": ""http://json-schema.org/draft-03/schema#"",
  ""id"": ""http://mycompany/derived-schema#"",
  ""type"": ""object"",

  ""extends"":{ ""$ref"": ""http://mycompany/base-schema#""},

  ""properties"": {
    ""lastName"": { ""type"": ""string"", ""required"": true}
  }
}
", resolver);

小提琴:https://dotnetfiddle.net/g1nFew

答案 2 :(得分:0)

我认为问题可能是您在$ref项中有相对URI,但没有id属性来建立基URI。您可以通过在最外层上下文中添加id="<absolute-url>"来确定可以从中检索外部文件的位置来解决您的问题。

http://json-schema.org/latest/json-schema-core.html

的第7节

P.S。在measure项中,我注意到您有$refdescription两个值。 json-reference网络草案说 JSON Reference对象中除“$ ref”以外的任何成员都应该被忽略。它可能没有任何伤害,但如果有人期望这样做可能会令人惊讶值以覆盖外部文件中的描述。