【问题标题】:Can't get JSON.NET Schema to find my externally referenced JSON schema files无法获取 JSON.NET 架构来查找我的外部引用的 JSON 架构文件
【发布时间】:2020-07-13 06:32:04
【问题描述】:

我正在尝试根据第三方提供的 JSON 模式来验证我创建的一些 REST Web API 函数的输出。我正在使用 .NET 4.8 控制台应用程序进行验证。

我正在使用 JSON.NET Schema (v3.0.0),并且一直在努力解决这个问题:我的 project-response.json 架构文件看起来像这样:

{
  "$id": "http://www.whereever.com/services/projects/project-response.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "project response definition",
  "type": "object",
  "properties": {
    ....
    "lead": {
      "description": "The lead person",
      "$ref": "common-types.json#/definitions/personType"
    },
    ....
  }
}

除其他外,它还包含对同一目录中 common-types.json 文件的引用,该文件定义了架构各个部分使用的一些基本类型 - 如下所示:

{
  "$id": "http://www.whereever.com/services/projects/common-types.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "common type definitions",
  "definitions": {
     ....
    "personType": {
      "type": "object",
      "properties": {
        "firstname": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        },
        "lastname": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        },
        "email": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256
        }
      },
      "required": [
        "firstname",
        "lastname"
      ]
    }, 
    

我得到一个 JSON 字符串作为 API 调用的响应,我想根据这个模式验证这个 JSON。我试过这样做:

public bool Validate(string jsonData)
{
    string jsonSchemaFileName = Path.Combine(_schemaBaseDirectory, "project-response.json");
    
    // define a Json Text Reader for the schema
    using (StreamReader schemaFile = File.OpenText(jsonSchemaFileName))
    using (JsonTextReader reader = new JsonTextReader(schemaFile))
    {
        JSchemaUrlResolver resolver = new JSchemaUrlResolver();

        JSchemaReaderSettings settings = new JSchemaReaderSettings
                                                 {
                                                     Resolver = resolver,
                                                     BaseUri = new Uri(jsonSchemaFileName)
                                                 };

        JSchema schema = JSchema.Load(jsonReader, settings);

        // validate
        JToken jsonToken = JObject.Parse(jsonData);

        bool isValid = jsonToken.IsValid(schema, out IList<string> errors);

        return isValid;
    }
}

我期待 JSON.NET Schema 系统现在能够从 project-response.json 所在的同一位置读取 common-types.json 并在该公共文件中查找定义 - 但唉,在线

JSchema schema = JSchema.Load(jsonReader, settings);

我不断收到错误:

Newtonsoft.Json.Schema.JSchemaReaderException
HResult=0x80131500
解析架构引用“common-types.json#/definitions/projectIdType”时出现消息=错误。路径“properties.id”,第 7 行,位置 11。

Source=Newtonsoft.Json.Schema

堆栈跟踪:
在 Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ResolveDeferedSchema(DeferedSchema deferedSchema) 在 Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ResolveDeferedSchemas() 在 Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ReadRoot(JsonReader 阅读器,布尔 resolveDeferedSchemas) 在 Newtonsoft.Json.Schema.JSchema.Load(JsonReader 阅读器,JSchemaReaderSettings 设置)

内部异常 1:
WebException:远程服务器返回错误:(404)未找到。

任何想法为什么会失败?我错过了什么重要的事情吗?

【问题讨论】:

    标签: c# json json.net jsonschema


    【解决方案1】:

    您需要从project-response.json 中删除$id,因为它将定义$ref 的基本网址。请参阅此link。 或者使用JSchemaPreloadedResolver预加载common-types.jsonlike

    JSchemaPreloadedResolver resolver = new JSchemaPreloadedResolver();
    using(var commontypes = File.Open(jsonSchemaCommonTypeFileName, FileMode.Open))
    {
        resolver.Add(new Uri("http://www.whereever.com/services/projects/common-types.json"), commontypes);
    }
    

    【讨论】:

    • 不幸的是,由于这个 JSON 模式是由外部第三方提供的,我无法控制他们在 $id 中使用的值.....
    • 在这种情况下,您可以使用JSchemaPreloadedResolver,并预加载common-type.json
    • 谢谢-该解决方案确实有效-有点令人失望,我必须做所有这些-但是哦-好吧-至少现在我可以根据架构验证我的JSON响应并获取必要的信息如果有什么不符合合同的!
    • $id 属性有什么问题?如果两个 json 文件在同一个目录下,那么它们是正确的,并且 $ref 正确使用 common-types.json 的 uri 引用。
    • @Ether 当 $id 存在时,似乎 BaseUri 不再使用,并且使用 http 请求来获取外部引用 - 这个地址实际上不存在
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 2012-10-11
    • 2021-04-15
    相关资源
    最近更新 更多