You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NJsonSchema未校验数据类型:age字段类型不符却校验通过

JSON Schema校验字符串类型age未触发错误的问题排查与解决

问题描述

我在JSON Schema中为age属性指定了number类型,但传入字符串类型的age值(如下方示例JSON)时,NJsonSchema仍能校验通过,请问问题出在哪里?

测试JSON

{"name":"alex", "age":"14", "task":"anyTask"}

JSON Schema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "name": {"type":"string"},
    "age": {"type": "number"},
    "task": {"type": "string"}
  },
  "required": [ "name", "age", "task" ]
}

测试代码

string shema = "{\"$schema\": \"http://json-schema.org/draft-04/schema#\",\"type\": \"object\",\"properties\": {\"name\": {\"type\":\"string\"},\"age\": {\"type\": \"number\"},\"task\": {\"type\": \"string\"}},\"required\": [ \"name\", \"age\", \"task\" ]}";
JSchema schemaWithRequiredParameters = JSchema.Parse(shema);

[TestCase("{\"name\":\"alex\", \"age\":\"14\", \"task\":\"anyTask\"}")]
public async Task Valid_IncompleteInputJson_ShemaWithRequiredParameters_NotValid(string json)
{
    Assert.IsFalse(await Validator.Valid(json, schemaWithRequiredParameters));
}

Validator类

public static async Task<bool> Valid(string json, JSchema schema)
{
    string schemaJson = System.Text.Json.JsonSerializer.Serialize(schema);

    var jsonSchema = await NJsonSchema.JsonSchema.FromJsonAsync(schemaJson);
    var errors = jsonSchema.Validate(json);
    foreach (var error in errors)
    {
        Console.WriteLine(error);
    }

    return errors.Count == 0;
}

问题原因

  1. NJsonSchema默认开启类型强制转换:NJsonSchema的Validate方法默认启用AllowTypeCoercion选项,会自动将可转换的字符串(如"14")转为对应数字类型,因此字符串格式的数字会被判定为符合number类型要求,校验通过。
  2. Schema处理流程冗余且混用组件:代码中先使用Newtonsoft.Json的JSchema.Parse解析Schema,再序列化后用NJsonSchema重新加载,这一步不仅多余,还可能导致Schema细节丢失或变形,增加不必要的风险。

解决方案

1. 关闭类型强制转换

调用Validate时传入ValidationSettings,明确禁用类型强制转换:

var errors = jsonSchema.Validate(json, new ValidationSettings
{
    AllowTypeCoercion = false
});

2. 简化Schema处理流程

直接使用NJsonSchema解析Schema字符串,避免混用Newtonsoft的JSchema组件:

  • 修改测试代码中的Schema初始化:
string schemaJson = "{\"$schema\": \"http://json-schema.org/draft-04/schema#\",\"type\": \"object\",\"properties\": {\"name\": {\"type\":\"string\"},\"age\": {\"type\": \"number\"},\"task\": {\"type\": \"string\"}},\"required\": [ \"name\", \"age\", \"task\" ]}";
var schemaWithRequiredParameters = await NJsonSchema.JsonSchema.FromJsonAsync(schemaJson);
  • 修改Validator类,移除多余的序列化/反序列化步骤:
public static bool Valid(string json, NJsonSchema.JsonSchema schema)
{
    var errors = schema.Validate(json, new ValidationSettings
    {
        AllowTypeCoercion = false
    });
    foreach (var error in errors)
    {
        Console.WriteLine(error);
    }
    return errors.Count == 0;
}

3. 调整测试方法逻辑

匹配修改后的Validator,简化异步流程:

[TestCase("{\"name\":\"alex\", \"age\":\"14\", \"task\":\"anyTask\"}")]
public async Task Valid_IncompleteInputJson_SchemaWithRequiredParameters_NotValid(string json)
{
    var schema = await NJsonSchema.JsonSchema.FromJsonAsync(schemaJson);
    Assert.IsFalse(Validator.Valid(json, schema));
}

内容的提问来源于stack exchange,提问作者ggg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:10:03