如何在.NET中查看JSON Schema OneOf的全部验证错误?
解决Json.NET中JSON Schema OneOf的完整错误收集问题
我之前也遇到过一模一样的情况——Json.NET的默认验证器在处理oneOf逻辑时,确实会优先返回第一个检测到的错误,不会遍历所有分支收集全部问题,这就是你只看到属性缺失错误、枚举无效被忽略的核心原因。下面是具体的解决方法:
1. 先搞懂默认行为的局限
Json.NET的默认验证逻辑在处理oneOf时,只要发现某个分支的验证错误,就可能停止检查其他分支;或者即使继续,也不会把所有分支的错误汇总返回。比如当输入缺少某个必填属性时,第一个分支直接验证失败,验证器可能不会再去检查另一个分支里的枚举值是否有效。
2. 自定义验证器收集所有oneOf分支错误
要获取全部错误,你需要自定义一个验证器,遍历oneOf下的所有子Schema,逐个验证并收集每个分支的错误,最后只有当所有分支都无效时,才把所有错误返回。
这里是一个可直接使用的自定义验证器实现:
public class OneOfFullErrorValidator : JsonValidator { public override void Validate(JToken value, JsonSchema schema, JsonSchemaValidator validator, IList<ValidationError> errors) { // 只处理包含oneOf规则的Schema if (schema.OneOf != null && schema.OneOf.Count > 0) { var allBranchErrors = new List<ValidationError>(); bool hasValidBranch = false; // 遍历每个oneOf分支,收集各自的错误 foreach (var subSchema in schema.OneOf) { var branchErrors = new List<ValidationError>(); validator.Validate(value, subSchema, branchErrors); if (branchErrors.Count == 0) { hasValidBranch = true; } allBranchErrors.AddRange(branchErrors); } // 如果没有任何分支验证通过,就把所有分支的错误都加入结果 if (!hasValidBranch) { errors.AddRange(allBranchErrors); // 可以额外添加一个总览错误,帮助理解问题 errors.Add(new ValidationError("输入不符合oneOf定义的任何一个Schema规则") { Schema = schema, Instance = value, Path = validator.CurrentPath }); } } else { // 非oneOf的情况,调用默认验证逻辑 base.Validate(value, schema, validator, errors); } } }
3. 配置验证设置并执行验证
接下来,你需要把自定义验证器加入到验证设置中,同时开启IncludeAllErrors确保错误不被过滤:
// 准备你的输入JSON和生成的Schema JToken input = JToken.Parse("你的错误输入JSON"); JsonSchema schema = // 你通过JSchemaGenerator生成的Schema // 配置验证设置 var validationSettings = new ValidationSettings { IncludeAllErrors = true, // 开启全错误收集 Validators = { new OneOfFullErrorValidator() } // 注册自定义验证器 }; // 执行验证并收集错误 var validationErrors = new List<ValidationError>(); JsonSchemaValidator.Validate(input, schema, validationSettings, validationErrors); // 输出所有错误信息 foreach (var error in validationErrors) { Console.WriteLine($"[{error.Path}] {error.Message}"); }
4. 额外检查:确保生成的Schema正确
在验证前,先确认你的oneOf Schema是否正确定义了枚举和必填属性。比如每个分支的enum字段是否正确,required属性是否包含了必要的字段——如果Schema本身定义有误,也会导致验证结果不符合预期。
这样处理后,你就能同时获取到属性缺失和枚举值无效两类错误了,每个错误都会标注对应的路径和原因,方便你定位问题。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

