如何获取JSON校验缺失Name属性的对象Id及排查自定义校验器未触发问题
问题解答
一、获取缺失Name属性的对象Id值
有三种可行的实现方式:
方式1:通过验证错误的Path定位对象
NewtonSoft返回的ValidationError包含Path属性,可通过该路径从JObject中定位到目标对象,再提取Id:
if (!valid) { foreach (var error in messages) { if (error.Message.Contains("Required properties are missing from object: Name")) { var targetObject = user.SelectToken(error.Path) as JObject; if (targetObject != null && targetObject.TryGetValue("Id", out JToken idToken)) { Console.WriteLine($"缺失Name的对象Id:{idToken.Value<int>()}"); } } } }
方式2:直接遍历JSON结构检查
遍历Contracts数组,逐个判断是否存在Name属性,不存在则记录Id:
JArray contracts = user["Contracts"] as JArray; if (contracts != null) { foreach (JObject contract in contracts) { if (!contract.ContainsKey("Name")) { int id = contract["Id"].Value<int>(); Console.WriteLine($"缺失Name的对象Id:{id}"); } } }
方式3:通过自定义校验器捕获Id
在自定义校验器中完成必填属性校验的同时,直接获取当前对象的Id并加入错误信息:
二、自定义校验器未触发的原因及修复
你的校验器未被触发,核心问题在于CanValidate的判断条件不符合实际场景:
- 条件不匹配:当前
CanValidate仅在schema的Format为"something"时返回true,但你的JSON Schema中,Contract对象的Name字段大概率未设置该格式,导致校验器不生效。 - 无实际校验逻辑:
Validate方法为空,即使触发也不会执行任何操作。
修复后的自定义校验器
调整CanValidate逻辑,使其匹配需要校验必填Name的对象场景,同时实现校验逻辑:
public class MyValidator : JsonValidator { public override void Validate(JToken value, JsonValidatorContext context) { if (value is JObject contractObj) { if (!contractObj.ContainsKey("Name")) { if (contractObj.TryGetValue("Id", out JToken idToken)) { string errorMsg = $"对象Id {idToken.Value<int>()} 缺失必填属性Name"; context.RaiseError(errorMsg, value.Path); } else { context.RaiseError("对象缺失必填属性Name且无Id", value.Path); } } } } public override bool CanValidate(JSchema schema) { // 匹配要求必填Name的对象类型schema return schema.Type == JSchemaType.Object && schema.Required.Contains("Name"); } }
注意事项
- 确保你的JSON Schema中,Contract对象定义明确标记
Name为必填(即包含"required": ["Name"]),否则CanValidate的条件无法匹配。 - 若要替代默认必填校验,需移除schema中的默认必填规则,完全由自定义校验器处理。
内容的提问来源于stack exchange,提问作者kudlatiger
相关产品推荐
相关产品推荐

