1

If I have a schema as follows:

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

And I'm using the following code to generate a set of C# classes:

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

And, using the resultant classes, perform this operation:

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

Then the deserialization completes without errors, but the resulting object o includes references to both object1 and object2, although all of object2's members are null.

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

What I need is for object2 to either not exist in the deserialized object, or set to null. Is there any way to do this, either in the schema itself or in one of the various processes involved in this pipeline?

fadedbee
  • 42,671
  • 44
  • 178
  • 308
Neil B
  • 113
  • 4

2 Answers2

3

Wouldn't that mean that your object2 is either null, or of the type you are looking for, so the schema changes required would be something like:

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

A similar example can be found on the github page where they show the company object

Icepickle
  • 12,689
  • 3
  • 34
  • 48
2

A rather rambling answer as I don't know C#.

GSON (Java) treats missing properties as nulls, NJsonSchema treats missing properties as default values of their types.

It looks like the unwanted initial values are generated by the template at a line like: https://github.com/RSuter/NJsonSchema/blob/1a50dfa4d5d562ae89e7aac49c1573ad4e32313a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid#L16

This is conditional on HasDefaultValue being true. This is set in 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 mentions _settings.GenerateDefaultValues. Perhaps you can set _settings.GenerateDefaultValues false?

From https://groups.google.com/forum/#!topic/jsonschema/mD6GDca4zN8 it looks like JSON schemas can have null values. Perhaps this would fix it, at the cost of adding text to the schema?

fadedbee
  • 42,671
  • 44
  • 178
  • 308