Как заставить нулевые несуществующие свойства?

Если у меня есть схема следующим образом:

{
  "id": "http://example.com/my_application",
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "my_application_schema",
  "additionalProperties": false,
  "definitions": {
    "NumberField": {
      "type": "number",
      "min": 0,
      "max": 2147483647
    },
    "StringField": {
      "type": "string",
      "minLength": 1,
      "maxLength": 12
    },
    "MainObject": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "object1": {
          "$ref": "#/definitions/Object1"
        },
        "object2": {
          "$ref": "#/definitions/Object2"
        }
      },
      "minProperties": 1,
      "maxProperties": 1
    },
    "Object1": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "field1": {
          "$ref": "#/definitions/NumberField",
          "proto_field": 1
        }
      },
      "required": [
        "field1"
      ]
    },
    "Object2": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "field1": {
          "$ref": "#/definitions/StringField",
          "proto_field": 1
        }
      },
      "required": [
        "field1"
      ]
    }
  },
  "type": "object",
  "properties": {
    "Content": {
      "$ref": "#/definitions/MainObject"
    }
  }
}

И я использую следующий код для генерации набора классов C#:

NJsonSchema.JsonSchema4 schema = await NJsonSchema.JsonSchema4.FromFileAsync(<path to schema>);
var generator = new CSharpGenerator(schema);
var file = generator.GenerateFile();

И, используя результирующие классы, выполните эту операцию:

My_application_schema o = JsonConvert.DeserializeObject<My_application_schema>(@"
            {
'Content': {
'object1': {
'field1': 20
}
}
}");

Затем десериализация завершается без ошибок, но результирующий объект o включает ссылки как на object1, так и на object2, хотя все члены object2 равны нулю.

JsonSerializerSettings settings = new JsonSerializerSettings()
{
    NullValueHandling = NullValueHandling.Ignore
};
String s = Newtonsoft.Json.JsonConvert.SerializeObject(o, settings);
// {"Content":{"object1":{"field1":20.0},"object2":{}}}

Что мне нужно, так это чтобы object2 либо не существовал в десериализованном объекте, либо имел значение null. Есть ли способ сделать это, либо в самой схеме, либо в одном из различных процессов, участвующих в этом конвейере?

2 ответа

Решение

Не означает ли это, что ваш object2 имеет значение null или того типа, который вы ищете, поэтому требуемые изменения схемы будут выглядеть примерно так:

"properties": {
  "object1":  {
    "oneOf": [
      {
        "$ref": "#/definitions/Object1"
      },
      {
        "type": "null"
      }
    ]
  },
  "object2": {
    "oneOf": [
      {
        "$ref": "#/definitions/Object2"
      },
      {
        "type": "null"
      }
    ]
  }
}

Подобный пример можно найти на странице GitHub, где они показывают объект компании

Довольно бессвязный ответ, поскольку я не знаю C#.

GSON (Java) рассматривает отсутствующие свойства как нули, NJsonSchema рассматривает отсутствующие свойства как значения по умолчанию их типов.

Похоже, что нежелательные начальные значения генерируются шаблоном в виде строки: https://github.com/RSuter/NJsonSchema/blob/1a50dfa4d5d562ae89e7aac49c1573ad4e32313a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid

Это обусловлено HasDefaultValue быть правдой Это установлено в https://github.com/RSuter/NJsonSchema/blob/1a50dfa4d5d562ae89e7aac49c1573ad4e32313a/src/NJsonSchema.CodeGeneration/Models/PropertyModelBase.cs#L40

https://github.com/RSuter/NJsonSchema/blob/1a50dfa4d5d562ae89e7aac49c1573ad4e32313a/src/NJsonSchema.CodeGeneration/Models/PropertyModelBase.cs#L50 упоминает _settings.GenerateDefaultValues, Возможно, вы можете установить _settings.GenerateDefaultValues ложный?

С https://groups.google.com/forum/ похоже, что схемы JSON могут иметь нулевые значения. Возможно, это исправит стоимость добавления текста в схему?

Другие вопросы по тегам