如何强制不存在的属性为null?

时间:2017-11-23 13:09:15

标签: c# njsonschema

如果我有如下架构:

{
  "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 个答案:

答案 0 :(得分:3)

这并不意味着您的object2为null或您正在寻找的类型,因此所需的架构更改将类似于:

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

可以在显示公司对象的github page上找到类似的示例

答案 1 :(得分:2)

一个相当漫无边际的答案,因为我不知道C#。

GSON(Java)将缺少的属性视为空值,NJsonSchema将缺失的属性视为其类型的默认值。

看起来不需要的初始值是由模板生成的,如:https://github.com/RSuter/NJsonSchema/blob/1a50dfa4d5d562ae89e7aac49c1573ad4e32313a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid#L16

这是以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 false?

https://groups.google.com/forum/#!topic/jsonschema/mD6GDca4zN8看起来JSON模式可以具有空值。也许这会解决它,但代价是在模式中添加文本?​​