Как проверить JSON через схему динамически в C # - PullRequest
1 голос
/ 15 октября 2019

Мне нужно динамически проверить ответ JSON. Схема должна зависеть от значения конкретного ключа в паре ключей.

Обратите внимание, что я использую JSON.NET 5.0.8 и не могу перейти на более новую версию из-за совместимости с инфраструктурой.

Если значение «type» не равно «SumProperty» (в примере «CountersProperty»), проверьте правильность строки «rule»:

"property": [
    {
        "type": "CountersProperty",
        "rule": "MEQUAL"
    }
]

Но! Если значение «type» равно «SumProperty», тогда проверьте «rule» как массив (и «rule» должно быть внутри «config»):

  "property": [
      {
          "type": "SumProperty",
          "config": {
              "rule": [
                  {
                      "type": "MEQUAL",
                      "value": 2
                  }
              ]
          }
      }
 ]

Так что мне нужна какая-то динамическая проверка, чтобыможет «понять», какая у нас есть собственность, и соответствующим образом проверить ее. Ответ JSON может иметь несколько «свойств» одновременно, поэтому я не могу выбрать тот или иной вид проверки, он должен работать динамически.

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Вы можете сделать это, внедрив пользовательский JsonConverter.

Я сделал следующие классы после вашего примера ввода

public class Schema
{
    [JsonProperty("Property")]
    public List<Property> Properties { get; set; }
}

public abstract class Property
{
    public string Type { get; set; }
}

public class NotSumProperty : Property
{
    public string Rule { get; set; }
}

public class SumProperty : Property
{
    public Config Config { get; set; }
}

public class Config
{
    [JsonProperty("Rule")]
    public List<Rule> Rules { get; set; }
}

public class Rule
{
    public string Type { get; set; }
    public int Value { get; set; }
}

Затем мы определяем наш пользовательский JsonConverter. Мы переопределяем метод ReadJson() для реализации нашего условия преобразования, в этом случае мы оцениваем type из Property.

public class PropertyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => typeof(Property).IsAssignableFrom(objectType);

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);
        Property p;

        switch ((string)obj["type"])
        {
            case "SumProperty":
                p = new SumProperty();
                break;
            default:
                p = new NotSumProperty();
                break;
        }

        serializer.Populate(obj.CreateReader(), p);
        return p;
    }
}

Наконец, вот использование:

JsonSerializerSettings settings = new JsonSerializerSettings 
{ 
    TypeNameHandling = TypeNameHandling.Objects 
};
settings.Converters.Add(new PropertyConverter());

Schema schema = JsonConvert.DeserializeObject<Schema>(json, settings);
0 голосов
/ 15 октября 2019

Другой вариант, если вы не хотите писать собственный конвертер, - это десериализовать в динамический объект и проверять эти значения во время выполнения, , как показано здесь .

Это может оказаться более полезным, если вы не можете определить чистый шаблон наследования, хотя он полагается на то, что клиенты сами реализуют больше логики синтаксического анализа / проверки. Другими словами, неожиданные исключения немного проще - в основном это переносит потенциальные проблемы от ошибок во время компиляции к ошибкам во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...