0

I am parsing the following JSON:

{"names":{"organizationNames":[{"name":"apple"}]}} 

into the schema defined in C# Code as shown below.

public class QueryJson
{

    #region Properties

    [JsonProperty("organization")]
    public HeOrganization Organization { get; set; }

    [JsonProperty("names")]
    public HeName Names { get; set; }

    [JsonProperty("emails")]
    public List<HeEmailAddress> Emails { get; set; }

    #endregion


    #region Linked Classes

    public class HeOrganization
    {
        [JsonProperty("id")]
        public Guid? ID { get; set; }
    }

    public class HeName
    {
        [JsonProperty("organizationNames")]
        [Required(ErrorMessage = "Organization Name is Missing")]
        public List<HeOrganizationName> OrganizationName { get; set; }

        public class HeOrganizationName
        {
            [JsonProperty("name")]
            [Required(ErrorMessage = "Name is Missing")]
            public string Name { get; set; }
        }
    }

    public class HeEmailAddress
    {
        [JsonProperty("address")]
        [Required]
        [EmailAddress]
        public string Address { get; set; }

    }

    #endregion

}

If I were to pass an obviously invalid JSON:

{"names":{"organizationNames":[{"user":"apple"}]}}

I was expecting DeserializeObject() to fail or throw an Error, but instead it simply assigns 'Name' to null.

var myJson = JsonConvert.DeserializeObject<T>(jsonFilter);

Where T is the instance of the class.

Any suggestion on how to perform such Validations?

Drag and Drop
  • 2,672
  • 3
  • 25
  • 37
Bugzy216
  • 1
  • 1
  • Have you tried : https://www.newtonsoft.com/jsonschema – Nitin Kabra Nov 15 '19 at 07:30
  • What type is T? It must be QueryJson class type eg: var myJson = JsonConvert.DeserializeObject(jsonFilter); – EmerG Nov 15 '19 at 07:39
  • It is JsonConvert.DeserializeObject(jsonFilter); – Bugzy216 Nov 15 '19 at 08:45
  • Json.NET doesn't honor [`RequiredAttribute`](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute?view=netframework-4.8), it honors [`[JsonProperty(Required = Required.Always)]`](https://www.newtonsoft.com/json/help/html/JsonPropertyRequired.htm). See: [Using Required and JsonRequired in ASP.NET Core Model Binding with JSON body](https://stackoverflow.com/q/49237767). Does that answer your question or do you need a workaround to make Json.NET honor `[RequiredAttribute]` for standalone serialization? – dbc Nov 15 '19 at 17:36

1 Answers1

0

You could use Newtonsoft.Json.Schema to validate the schema of any given Json.

For example, for the class structure you have defined, an equivalent Schema could be generated as

var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(QueryJson));

The Generated Schema is as follows

{
  "definitions": {
    "HeEmailAddress": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "address": {
          "type": "string",
          "format": "email"
        }
      },
      "required": [
        "address"
      ]
    },
    "HeName": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "organizationNames": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/HeOrganizationName"
          }
        }
      },
      "required": [
        "organizationNames"
      ]
    },
    "HeOrganization": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "id": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "id"
      ]
    },
    "HeOrganizationName": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "name": {
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    }
  },
  "type": "object",
  "properties": {
    "organization": {
      "$ref": "#/definitions/HeOrganization"
    },
    "names": {
      "$ref": "#/definitions/HeName"
    },
    "emails": {
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "#/definitions/HeEmailAddress"
      }
    }
  },
  "required": [
    "organization",
    "names",
    "emails"
  ]
}

You could now use the Schema to validate your jsons. For example, for the sample invalid json provided in OP

var invalidJson = @"{""names"":{""organizationNames"":[{""user"":""apple""}]}}";
var jsonInstance = JObject.Parse(invalidJson);
bool valid = jsonInstance.IsValid(schema); // False
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • This is helpful, thanks! But I have a follow-up question - Why are the properties organization, names and emails generated as required? What if I don't want it to be required? – Bugzy216 Nov 18 '19 at 04:54
  • This might be useful https://github.com/JamesNK/Newtonsoft.Json.Schema/issues/9 – Anu Viswan Nov 18 '19 at 05:35