Custom JSON validation rules |
Json.NET Schema lets you extend JSON Schema with your own custom validation rules using JsonValidator.
Custom validation rules are created by implementing a JsonValidator and its two abstract methods.
Validate(JToken, JsonValidatorContext) is called when validating the schema against JSON. It tests the JSON being validated by the schema and raises validation errors.
CanValidate(JSchema) is called when loading a JSchema and determines whether the validator will run when the schema is validated.
public class CultureFormatValidator : JsonValidator { public override void Validate(JToken value, JsonValidatorContext context) { if (value.Type == JTokenType.String) { string s = value.ToString(); try { // test whether the string is a known culture, e.g. en-US, fr-FR new CultureInfo(s); } catch (CultureNotFoundException) { context.RaiseError($"Text '{s}' is not a valid culture name."); } } } public override bool CanValidate(JSchema schema) { // validator will run when a schema has a format of culture return (schema.Format == "culture"); } }
Custom rules must be specified when loading the schema that will use them. Add custom JsonValidator instances to the Validators collection on JSchemaReaderSettings and then load the schema using Parse(String, JSchemaReaderSettings).
Once the JSchema has been loaded validate JSON as usual. Custom validation rules will be executed along-side normal JSON Schema validation.
string json = @"[ 'en-US', 'en-GB', 'fr-FR', 'purple monkey dishwasher', 1234 ]"; JSchemaReaderSettings settings = new JSchemaReaderSettings { Validators = new List<JsonValidator> { new CultureFormatValidator() } }; // the culture validator will be used to validate the array items JSchema schema = JSchema.Parse(@"{ 'type': 'array', 'items': { 'type': 'string', 'format': 'culture' } }", settings); JArray cultures = JArray.Parse(json); IList<ValidationError> errors; bool isValid = cultures.IsValid(schema, out errors); // false Console.WriteLine(isValid); // Text 'purple monkey dishwasher' is not a valid culture name. Console.WriteLine(errors[0].Message); // Invalid type. Expected String but got Integer. Console.WriteLine(errors[1].Message);