Validating JSON with JSON Schema |
Json.NET supports the JSON Schema standard via the JsonSchema and JsonValidatingReader classes. It sits under the Newtonsoft.Json.Schema namespace.
JSON Schema is used to validate the structure and data types of a piece of JSON, similar to XML Schema for XML. You can read more about JSON Schema at json-schema.org
Caution |
---|
Obsolete. JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details. |
The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then use the IsValid(JToken, JsonSchema) method with the JSON Schema.
string schemaJson = @"{ 'description': 'A person', 'type': 'object', 'properties': { 'name': {'type':'string'}, 'hobbies': { 'type': 'array', 'items': {'type':'string'} } } }"; JsonSchema schema = JsonSchema.Parse(schemaJson); JObject person = JObject.Parse(@"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"); bool valid = person.IsValid(schema); // true
To get validation error messages, use the IsValid(JToken, JsonSchema, IListString) or Validate(JToken, JsonSchema, ValidationEventHandler) overloads.
JsonSchema schema = JsonSchema.Parse(schemaJson); JObject person = JObject.Parse(@"{ 'name': null, 'hobbies': ['Invalid content', 0.123456789] }"); IList<string> messages; bool valid = person.IsValid(schema, out messages); // false // Invalid type. Expected String but got Null. Line 2, position 21. // Invalid type. Expected String but got Float. Line 3, position 51.
Internally IsValid uses JsonValidatingReader to perform the JSON Schema validation. To skip the overhead of loading JSON into a JObject/JArray, validating the JSON, and then deserializing the JSON into a class, JsonValidatingReader can be used with JsonSerializer to validate JSON while the object is being deserialized.
string json = @"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"; JsonTextReader reader = new JsonTextReader(new StringReader(json)); JsonValidatingReader validatingReader = new JsonValidatingReader(reader); validatingReader.Schema = JsonSchema.Parse(schemaJson); IList<string> messages = new List<string>(); validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message); JsonSerializer serializer = new JsonSerializer(); Person p = serializer.Deserialize<Person>(validatingReader);
The simplest way to get a JsonSchema object is to load it from a string or a file.
// load from a string JsonSchema schema1 = JsonSchema.Parse(@"{'type':'object'}"); // load from a file using (TextReader reader = File.OpenText(@"c:\schema\Person.json")) { JsonSchema schema2 = JsonSchema.Read(new JsonTextReader(reader)); // do stuff }
It is also possible to create JsonSchema objects in code.
JsonSchema schema = new JsonSchema(); schema.Type = JsonSchemaType.Object; schema.Properties = new Dictionary<string, JsonSchema> { { "name", new JsonSchema { Type = JsonSchemaType.String } }, { "hobbies", new JsonSchema { Type = JsonSchemaType.Array, Items = new List<JsonSchema> { new JsonSchema { Type = JsonSchemaType.String } } } }, }; JObject person = JObject.Parse(@"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"); bool valid = person.IsValid(schema); // true