如何在C#中用JSON Schema完整校验JSON并获取全部错误
JSON Schema校验问题求助
我用以下代码校验API返回的JSON数据是否符合JSON Schema:
string data = File.ReadAllText(@"C:\Users\Aman.Sharma\Source\Repos\Validator\Validator\testData.json"); string schema = File.ReadAllText(@"C:\Users\Aman.Sharma\Source\Repos\Validator\Validator\V2JsonSchema.json"); var model = JObject.Parse(data); var json_schema = JSchema.Parse(schema); bool valid = model.IsValid(json_schema, out IList<string> messages);
现在遇到两个问题:
- 校验只返回第一个错误,没法拿到所有不符合Schema的错误记录;
- 修改Schema后,校验结果始终显示JSON合法,完全没反应。
求问怎么实现全量校验,返回所有错误?
示例数据
{ "id": "e1110047-b606-4fb3-84c6-28f7d5456e11", "accountInactiveDate": "0001-01-01T00:00:00Z", "accountOpenDate": "0001-01-01T00:00:00Z", "accountTypeIds": [ 4000 ], "address": { "city": "vVjEKwUP", "addressTypeId": 1000, "countryISOCode": "GBR", "street1": "xTMksdLL", "zipCode": "12345" }, "annualRevenue": 0.0, "email": { "emailTypeId": 1000, "email": "zvvzwsdv@yopmail.com" }, "homeLocationNumber": "316", "industryTypeId": 0, "isDeleted": false, "name": "AccounttxecJizQ", "parentAccountId": "00000000-0000-0000-0000-000000000000", "phone": { "phoneTypeId": 1000, "number": "+44 123456" }, "productsTypeIds": [ 3000 ], "timeStamp": "\"2e001932-0000-0d00-0000-63315d8e0000\"", "links": [ { "href": "https://api-test.QA.cloud/companies/api/v2/accounts/e1110047-b606-4fb3-84c6-28f7d5456e11", "rel": "Self" } ], "isBlocked": false, "isComplete": true, "createDate": "2022-09-26T08:06:38.2263447Z", "systemCaller": "qa-user2-automationtests", "originSystemCaller": "qa-user2-automationtests", "originCreateDate": "2022-09-26T08:06:38.2263447Z" }
对应的Schema
{ "type": "object", "properties": { "searchMode": { "enum": [ "Any", "All" ], "type": "string" }, "queryType": { "enum": [ "Simple", "Full" ], "type": "string" }, "select": { "type": "array", "items": { "type": "string" } }, "searchFields": { "type": "array", "items": { "type": "string" } }, "orderBy": { "type": "array", "items": { "type": "string" } }, "highlightPreTag": { "type": "string" }, "highlightPostTag": { "type": "string" }, "highlightFields": { "type": "array", "items": { "type": "string" } }, "filter": { "type": "string" }, "facets": { "type": "array", "items": { "type": "string" } }, "scoringProfile": { "type": "string" }, "scoringParameters": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "values": { "type": "array", "items": { "type": "string" } } } } }, "page": { "format": "int32", "type": "integer" }, "pageSize": { "format": "int32", "type": "integer" }, "includeTotalResultCount": { "type": "boolean" } } }
解决方案
问题1:获取所有校验错误
默认的IsValid方法只会返回第一个错误,要收集所有错误,需要使用JSchemaValidatingReader手动遍历JSON并捕获所有校验异常:
string data = File.ReadAllText(@"C:\Users\Aman.Sharma\Source\Repos\Validator\Validator\testData.json"); string schemaContent = File.ReadAllText(@"C:\Users\Aman.Sharma\Source\Repos\Validator\Validator\V2JsonSchema.json"); var schema = JSchema.Parse(schemaContent); var jsonReader = new JsonTextReader(new StringReader(data)); var validatingReader = new JSchemaValidatingReader(jsonReader) { Schema = schema }; var validationErrors = new List<string>(); validatingReader.ValidationEventHandler += (sender, args) => { validationErrors.Add(args.Message); }; // 遍历整个JSON触发全量校验 try { while (validatingReader.Read()) { } } catch (JsonReaderException) { validationErrors.Add("JSON格式无效"); } bool isValid = validationErrors.Count == 0; // 输出所有错误 foreach (var error in validationErrors) { Console.WriteLine(error); }
问题2:修改Schema后校验结果不变
这个问题核心原因是Schema默认允许额外属性,你的示例数据和Schema完全不匹配(一个是账户信息,一个是搜索参数),但因为没设置additionalProperties: false,JSON里的额外属性不会被判定为错误。
解决步骤:
- 在Schema的根对象添加
"additionalProperties": false,这样JSON中出现Schema未定义的属性时会触发错误:
{ "type": "object", "additionalProperties": false, // 新增此行 "properties": { // ... 原有属性定义 ... } }
- 确保修改后的Schema文件被正确读取:可以明确指定编码读取(
File.ReadAllText(path, Encoding.UTF8)),或者重启调试进程避免文件缓存问题。
额外说明
你的示例数据和Schema完全不匹配,添加additionalProperties: false后,校验会返回大量错误(比如属性'id'未被Schema定义),这才是正确的校验结果。
内容的提问来源于stack exchange,提问作者Aman Sharma
相关产品推荐
相关产品推荐

