How to reference external files with JSON.net?

ⅰ亾dé卋堺 提交于 2019-12-22 13:57:26

问题


Here is the error I am getting when JSON.net is trying to read my JSON schema ( 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

My JSON schema:

{
  "$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."
    }
  },
}

My problem is that I have this JSON schema with this reference to an external file, data-result.json, but JSON.net does not yet know it exists. Is there some sort of fix for this? One idea I have is to skim through the schema, and if there are any references to external files, to parse those with a common JsonSchemaResolver. I'd have to add IDs as appropriate, since it looks like $ref likes to match by the ID, even though over at json-schema.org, there are clear examples of $ref being used with file names. I'd like to know if there is a better way that JSON.net natively supports referencing external schemas.

The source code is hosted on Github, if it helps. I have tested with the $ref field removed, and it compiles successfully.


回答1:


Json.NET Schema has much improved support for resolving external references.

Read more here: http://www.newtonsoft.com/jsonschema/help/html/LoadingSchemas.htm




回答2:


One idea I have is to skim through the schema, and if there are any references to external files, to parse those with a common JsonSchemaResolver

Yes, you need to know which schemas your schema depends on, parse those first and add them to a JsonSchemaResolver. The schemas will be resolved using their IDs.

Here's an example (using draft-03 syntax):

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);

Fiddle: https://dotnetfiddle.net/g1nFew




回答3:


I think the problem may be that you have relative URI's in those $ref items, but no id properties to establish a base URI. You may be able to resolve your problem by adding id="<absolute-url>"in the outermost context establishing where those external files can be retrieved from.

See section 7 of http://json-schema.org/latest/json-schema-core.html

P.S. In your measure item, I notice you have both a $ref and description values. The json-reference internet draft says Any members other than "$ref" in a JSON Reference object SHALL be ignored. It probably doesn't do any harm, but could be surprising if someone was to expect that value to override the description in the external file.



来源:https://stackoverflow.com/questions/24768479/how-to-reference-external-files-with-json-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!