Is there a way to validate a JSON structure against a JSON schema for that structure? I have looked and found JSON.Net validate but this does not do what I want.
JSON.net does:
JsonSchema schema = JsonSchema.Parse(@"{ 'type': 'object', 'properties': { 'name': {'type':'string'}, 'hobbies': {'type': 'array'} } }"); JObject person = JObject.Parse(@"{ 'name': 'James', 'hobbies': ['.NET', 'LOLCATS'] }"); bool valid = person.IsValid(schema); // true
This validates to true.
JsonSchema schema = JsonSchema.Parse(@"{ 'type': 'object', 'properties': { 'name': {'type':'string'}, 'hobbies': {'type': 'array'} } }"); JObject person = JObject.Parse(@"{ 'surname': 2, 'hobbies': ['.NET', 'LOLCATS'] }"); bool valid = person.IsValid(schema);
This also validates to true
JsonSchema schema = JsonSchema.Parse(@"{ 'type': 'object', 'properties': { 'name': {'type':'string'}, 'hobbies': {'type': 'array'} } }"); JObject person = JObject.Parse(@"{ 'name': 2, 'hobbies': ['.NET', 'LOLCATS'] }"); bool valid = person.IsValid(schema);
Only this validates to false.
Ideally I would like it to Validate that there are no fields aka name
in there that shouldn't be in there aka surname
.
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. To get validation error messages, use the IsValid(JToken, JsonSchema, IList<String> ) or Validate(JToken, JsonSchema, ValidationEventHandler) overloads.
JSON Schema is a powerful tool. It enables you to validate your JSON structure and make sure it meets the required API. You can create a schema as complex and nested as you need, all you need are the requirements. You can add it to your code as an additional test or in run-time.
JSON Schema Validation: The JSON Schema Validation specification is the document that defines the valid ways to define validation constraints. This document also defines a set of keywords that can be used to specify validations for a JSON API.
I think that you just need to add
'additionalProperties': false
to your schema. This will stop unknown properties being provided.
So now your results will be:- True, False, False
test code....
void Main() { var schema = JsonSchema.Parse( @"{ 'type': 'object', 'properties': { 'name': {'type':'string'}, 'hobbies': {'type': 'array'} }, 'additionalProperties': false }"); IsValid(JObject.Parse( @"{ 'name': 'James', 'hobbies': ['.NET', 'LOLCATS'] }"), schema).Dump(); IsValid(JObject.Parse( @"{ 'surname': 2, 'hobbies': ['.NET', 'LOLCATS'] }"), schema).Dump(); IsValid(JObject.Parse( @"{ 'name': 2, 'hobbies': ['.NET', 'LOLCATS'] }"), schema).Dump(); } public bool IsValid(JObject obj, JsonSchema schema) { return obj.IsValid(schema); }
output :-
True False False
You could also add "required":true to the fields that must be supplied that way you can return a message with details of missing/invalid fields:-
Property 'surname' has not been defined and the schema does not allow additional properties. Line 2, position 19. Required properties are missing from object: name. Invalid type. Expected String but got Integer. Line 2, position 18.
Ok i hope this will help.
This is your schema:
public class test { public string Name { get; set; } public string ID { get; set; } }
This is your validator:
/// <summary> /// extension that validates if Json string is copmplient to TSchema. /// </summary> /// <typeparam name="TSchema">schema</typeparam> /// <param name="value">json string</param> /// <returns>is valid?</returns> public static bool IsJsonValid<TSchema>(this string value) where TSchema : new() { bool res = true; //this is a .net object look for it in msdn JavaScriptSerializer ser = new JavaScriptSerializer(); //first serialize the string to object. var obj = ser.Deserialize<TSchema>(value); //get all properties of schema object var properties = typeof(TSchema).GetProperties(); //iterate on all properties and test. foreach (PropertyInfo info in properties) { // i went on if null value then json string isnt schema complient but you can do what ever test you like her. var valueOfProp = obj.GetType().GetProperty(info.Name).GetValue(obj, null); if (valueOfProp == null) res = false; } return res; }
And how to use is:
string json = "{Name:'blabla',ID:'1'}"; bool res = json.IsJsonValid<test>();
If you have any question please ask, hope this helps, please take into consideration that this isn't a complete code without exception handling and such...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With