在自定义JsonValidator中访问字段父级

时间:2016-05-06 14:49:59

标签: c# .net json.net jsonschema

我正在使用Newtonsoft优秀的JsonSchema lib并尝试为greaterthanfield另一个字段验证构建自定义验证器。

为了做到这一点,我显然需要从Validate(JToken value, JsonValidatorContext context)方法访问其他字段。但是,JToken存在没有任何父信息才能找到所需的兄弟。同样地,JsonValidatorContext仅对模式的验证数据没有任何引用。

我希望能够: value.Parent["siblingkey"]但似乎JToken实际上就是那个令牌而无法访问其余解析数据。

有谁知道实现这种验证器的方法?一个引用其他字段。其他例子可能是combinedmaxlength等...

2 个答案:

答案 0 :(得分:2)

我一直在玩,因为我遇到了同样的问题 我发现自定义验证器系统有一些奇怪的行为,其中JToken树基于验证器可以验证的最高父节点重新构建(其中CanValidate返回true)

这意味着如果我们可以诱骗系统相信您的验证工具可以验证根令牌您的特定令牌,那么您的树就会被充实。

public class TestValidator : JsonValidator
{

    public override bool CanValidate(JSchema schema)
    {
        // we assume every schema has a title/schemaversion in its root object.
        return schema.Title != null || schema.SchemaVersion != null || schema.ExtensionData.ContainsKey("greaterthanfield");
    }

    public override void Validate(JToken value, JsonValidatorContext context)
    {
        // we should ignore the "root token validation"
        if (!context.Schema.ExtensionData.ContainsKey("greaterthanfield"))
            return;
        // value.Parent is hydrated now
    }
}

答案 1 :(得分:-1)

我刚遇到这个问题。我在属性级别上应用了自定义验证器(使用"格式"),但这些验证器不起作用。

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "title": "JSON Schema for custom rule",

  "type": "object",

  "properties": {
    "Prop1": {
      "type": "string"
    },
    "Prop2": {
      "type": "string",
      "format": "YourCustomValidatorName"
    }
  }
}

您需要将自定义验证程序应用于整个架构。

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "title": "JSON Schema for custom rule",

  "type": "object",

  "properties": {
    "Prop1": {
      "type": "string"
    },
    "Prop2": {
      "type": "string"
    }
  },

  "format": "YourCustomValidatorName"
}

然后在您的自定义验证器类中,您将能够访问所有属性

public override void Validate(JToken value, JsonValidatorContext context)
{
    var prop1 = value.SelectToken("..Prop1")?.Value<string>();
    var prop2 = value.SelectToken("..Prop2")?.Value<string>();

    // Rest of your logic...
}