Родитель поля доступа в пользовательском JsonValidator

Я использую превосходную библиотеку Newsonoft JsonSchema и пытаюсь создать собственный валидатор для greaterthanfield проверка другого поля.

Для этого мне, очевидно, нужно получить доступ к другому полю из Validate(JToken value, JsonValidatorContext context) метод. Тем не менее JToken У настоящего нет родительской информации, чтобы найти нужного брата или сестру. Аналогично JsonValidatorContext не имеет никакой ссылки на данные проверки, только схема.

Я надеялся, что смогу просто:value.Parent["siblingkey"] но, похоже, JToken буквально просто этот токен без доступа к остальным проанализированным данным.

Кто-нибудь знает способ реализации такого валидатора? Тот, который ссылается на другие поля. Другие примеры будут что-то вроде combinedmaxlength так далее...

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
    }
}

У меня только что была эта проблема. Я применял пользовательские валидаторы (используя "Формат") на уровне свойств, который не работал.

{
  "$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...
}
Другие вопросы по тегам