我使用JsonSchema.Net(docs)根据准备好的模式来验证JSON文档.一些属性在模式中被定义为可为空(as described in the documentation,{"oneOf":[{"type":"string"},{"type":"null"}]})

当我对照模式判断文档时,一些可为空的属性的计算细节将返回IsValid = false,错误与JSON中的错误相反(例如"Value is "null" but should be "integer"""Value is "number" but should be "null"").

我想知道在这种情况下我可能做错了什么.我如何过滤这种误报,以便如果Json文档无效,我可以快速找到导致这些错误的 node ,以及它们的问题所在.

文档示例:

{
  "referenceNumber": "35366",
  "storageZone": null,
  "maxCount": null,
  "length":  124.5
}

文档的Json架构:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Schema Example",
  "$defs": {
    "stringNullable": {
      "oneOf": [
        { "type": "string" },
        { "type": "null" }
      ]
    },
    "integerNullable": {
      "oneOf": [
        { "type": "integer" },
        { "type": "null" }
      ]
    },
    "numberNullable": {
      "oneOf": [
        { "type": "number" },
        { "type": "null" }
      ]
    }
  },
  "type": "object",
  "properties": {
    "referenceNumber": {
      "type": "string"
    },
    "storageZone": {
      "$ref": "#/$defs/stringNullable"
    },
    "maxCount": {
      "$ref": "#/$defs/integerNullable"
    },
    "length": {
      "$ref": "#/$defs/numberNullable"
    }
  }
}

代码示例:

[Test]
public void JsonSchemaAsserts()
{
    var schema = JsonSchema.FromFile("./SchemaExample.json");
    var jsonText = File.ReadAllText("./DataExample.json");
    var json = JsonNode.Parse(jsonText);

    var validationResult = schema.Evaluate(json, new EvaluationOptions() { OutputFormat = OutputFormat.List });

    Assert.That(validationResult.IsValid, Is.True);

    var validationErrors = validationResult.Details.Where(d => !d.IsValid && d.HasErrors).ToList();

    Assert.That(validationResult, Is.Empty);
}

推荐答案

因为您使用的是oneOf,所以当验证多个模式时,总会有一个false模式.

如果您希望以一种更简洁的方式编写相同的模式,则可以使用type的数组形式.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Schema Example",
  "$defs": {
    "stringNullable": {
      "type": [
        "string",
        "null"
      ]
    },
    "integerNullable": {
      "type": [
        "integer",
        "null"
      ]
    },
    "numberNullable": {
      "type": [
        "number",
        "null"
      ]
    }
  },
  "type": "object",
  "properties": {
    "referenceNumber": {
      "type": "string"
    },
    "storageZone": {
      "$ref": "#/$defs/stringNullable"
    },
    "maxCount": {
      "$ref": "#/$defs/integerNullable"
    },
    "length": {
      "$ref": "#/$defs/numberNullable"
    }
  }
}

这将产生以下结果

{
  "valid": true,
  "evaluationPath": "",
  "schemaLocation": "https://json-everything.net/2f7acd351a#",
  "instanceLocation": "",
  "annotations": {
    "title": "Schema Example",
    "properties": [
      "referenceNumber",
      "storageZone",
      "maxCount",
      "length"
    ]
  },
  "details": [
    {
      "valid": true,
      "evaluationPath": "/properties/referenceNumber",
      "schemaLocation": "https://json-everything.net/2f7acd351a#/properties/referenceNumber",
      "instanceLocation": "/referenceNumber"
    },
    {
      "valid": true,
      "evaluationPath": "/properties/storageZone",
      "schemaLocation": "https://json-everything.net/2f7acd351a#/properties/storageZone",
      "instanceLocation": "/storageZone",
      "details": [
        {
          "valid": true,
          "evaluationPath": "/properties/storageZone/$ref",
          "schemaLocation": "https://json-everything.net/2f7acd351a#/$defs/stringNullable",
          "instanceLocation": "/storageZone"
        }
      ]
    },
    {
      "valid": true,
      "evaluationPath": "/properties/maxCount",
      "schemaLocation": "https://json-everything.net/2f7acd351a#/properties/maxCount",
      "instanceLocation": "/maxCount",
      "details": [
        {
          "valid": true,
          "evaluationPath": "/properties/maxCount/$ref",
          "schemaLocation": "https://json-everything.net/2f7acd351a#/$defs/integerNullable",
          "instanceLocation": "/maxCount"
        }
      ]
    },
    {
      "valid": true,
      "evaluationPath": "/properties/length",
      "schemaLocation": "https://json-everything.net/2f7acd351a#/properties/length",
      "instanceLocation": "/length",
      "details": [
        {
          "valid": true,
          "evaluationPath": "/properties/length/$ref",
          "schemaLocation": "https://json-everything.net/2f7acd351a#/$defs/numberNullable",
          "instanceLocation": "/length"
        }
      ]
    }
  ]
}

Csharp相关问答推荐

C#中的包版本控制

Dapper是否可以自动扩展类成员

使用变量子根名称在C#中重新初始化SON文件

CsWin32如何创建PWSTR的实例,例如GetWindowText

数组被内部函数租用时,如何将数组返回给ArrayPool?

如果属性名为xyz,我需要使用System.Text.Json修改字符串类型的值""<>

REST API端点中异步后台代码执行的类型

有没有办法在WPF文本框中添加复制事件的处理程序?

附加标题不起作用,而添加则起作用

StackExchange.Redis.RedisServerException:调用ITransaction.ExecuteAsync()时出现错误未知命令取消监视

当我没有此令牌时,为什么语法报告EOF错误?

当试图限制EF Select 的列时,如何避免重复代码?

异步任务调用程序集

C#Microsoft.CodeAnalysis.CSharp.Scriiting不等待并行.对于

将列表转换为带有逗号分隔字符串形式的值的字典

如果所有";async任务方法()";调用都返回Task.FromResult()-是否同步执行?

客户端/服务器RPC如何处理全局变量?

使用生产环境调试我的应用程序的快速方法

缩写的MonthNames有问题

在Blazor中动态隐藏MUD文本