Json Schema Example For .Net Derived Types
If you have ever worked with json you probably have needed to validate it to make sure it is structured properly for your application to understand. I recently had to validate some json where the object had an array of items and those items each derived from a base class. I’ll describe how I made a json schema file and then how to validate it using Newtonsoft’s Json schema library.
For information about json schema be sure to check out the official site here.
A very simple json schema for a Person
object that has a few properties would look like this.
{
"$id": "https://example.com/person.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"required": ["firstName", "lastName"],
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
}
}
Using Json Schema validator
It’s fairly simple and you can test that schema out against an actual json document like this at this url: https://www.jsonschemavalidator.net/s/TIIl3bA9
{
"firstName": "John",
"lastName": "Doe",
"age": 21
}
Try changing the input json to change the firstName
to something like first
and you will see that the validation will fail.
Now for the examle of a schema for inherited classes. The objects that I will be serializing will look like this:
public class Garage
{
public string Name { get; set; }
public Vehicle[] Vehicles { get; set; }
}
public class Vehicle
{
public string Make { get; set; }
public string Model { get; set; }
public Color Color { get; set; }
}
public class OffRoadVehicle : Vehicle
{
public string OffRoadUniqueProperty { get; set; }
}
public class Truck : Vehicle
{
public string TruckUniqueProperty { get; set; }
}
public class RaceCar : Vehicle
{
public bool WonMedals { get; set; }
}
The garage object will produce json that looks like this:
{
"Name": "My Garage",
"Vehicles": [
{
"$type": "GarageApp.OffRoadVehicle, GarageApp",
"OffRoadUniqueProperty": "the best off road vehicle",
"Make": "Custom",
"Model": "Custom",
"Color": "Black"
},
{
"$type": "GarageApp.RaceCar, GarageApp",
"WonMedals": true,
"Make": "Formula 1",
"Model": "Custom",
"Color": "Red"
},
{
"$type": "GarageApp.Truck, GarageApp",
"TruckUniqueProperty": "A great truck",
"Make": "GMC",
"Model": "Sierra",
"Color": "Blue"
}
]
}
So the json schema that I came up with to validate that uses the oneOf
property and then proceeds to specify the schema of each derived vehicle type importantly including the $type
property. I mark them all as required to check to make sure it is valid:
{
"$id": "https://example.com/person.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Garage",
"type": "object",
"required": [
"Name",
"Vehicles"
],
"properties": {
"Name": {
"type": "string",
"description": "The Garage's name."
},
"Vehicles": {
"type": "array",
"description": "The list of vehicles",
"items": {
"oneOf": [
{
"type": "object",
"required": [
"$type",
"Make",
"Model",
"Color",
"OffRoadUniqueProperty"
],
"additionalProperties": false,
"properties": {
"$type": {
"const": "GarageApp.OffRoadVehicle, GarageApp"
},
"Make": {
"type": "string"
},
"Model": {
"type": "string"
},
"Color": {
"type": "string"
},
"OffRoadUniqueProperty": {
"type": "string"
}
}
},
{
"type": "object",
"required": [
"$type",
"Make",
"Model",
"Color",
"WonMedals"
],
"additionalProperties": false,
"properties": {
"$type": {
"const": "GarageApp.RaceCar, GarageApp"
},
"Make": {
"type": "string"
},
"Model": {
"type": "string"
},
"Color": {
"type": "string"
},
"WonMedals": {
"type": "boolean"
}
}
},
{
"type": "object",
"required": [
"$type",
"Make",
"Model",
"Color",
"TruckUniqueProperty"
],
"additionalProperties": false,
"properties": {
"$type": {
"const": "GarageApp.Truck, GarageApp"
},
"Make": {
"type": "string"
},
"Model": {
"type": "string"
},
"Color": {
"type": "string"
},
"TruckUniqueProperty": {
"type": "string"
}
}
}
]
}
}
}
}
You can test that example out here.
You also might have noticed the additionalProperties
which I set to false. This disallows any other properties to be added to the input json.
To validate a schema in a .net application be sure to get the Newtonsoft.Json.Schema from nuget.
Conclusion
Json schema is a powerful way to check to make sure your json is in the form you want it, nothing more, nothing less. This example showed how to make a schema that will validate derived classes in an array.