3

I want to validate a schema which has an array, all in one call to the validate method. I did it in javascript but I am sturggling to do it in C# with Json.NET. With Json.NET I am calling the validation method for each object in the array like so:

JSchema schema = JSchema.Parse(@"{
                'title': 'HouseCollection',
    'description': '',
    '$schema': 'http://json-schema.org/draft-04/schema#',
    'definitions': {
                    'Categories': {
                        'title': 'Categories',
            'description': '',
            '$schema': 'http://json-schema.org/draft-04/schema#',
            'type': 'object',
            'additionalProperties': false,
            'properties': {
                            'serviceCode': {
                                'description': 'xxx,
                    'type': 'string'
                            }
                        },
            'required': [
                'serviceCode'
            ]
    },
        'House': {
            'title': 'House',
            'description': '',
            '$schema': 'http://json-schema.org/draft-04/schema#',
            'type': 'object',
            'additionalProperties': false,
            'properties': {
                'aaa': {
                    'type': 'string'
                },
                'bbb': {
                    'type': 'string'
                },
                'ccc': {
                    'description': 'xxx',
                    'type': 'string'
                },
                'ddd': {
                    'type': 'number'
                },
                'eee': {
                    'description': 'xxx',
                    'type': 'boolean'
                },
                'fff': {
                    'description': 'xxx',
                    'type': 'string'
                },
                'ggg': {
                    'description': 'xxx',
                    'type': 'string'
                },
                'hhh': {
                    'type': 'number'
                },
                'iii': {
                    'description': 'xxx',
                    'type': 'string'
                },
                'jjj': {
                    'type': 'string'
                },
                'kkk': {
                    'description': 'xxx',
                    'type': 'string'
                },
                'lll': {
                    'description': 'xxx',
                    'type': 'string'
                },
                'mmm': {
                    'description': '',
                    'type': 'string'
                },
                'nnn': {
                    'description': '',
                    'type': 'array',
                    'items': {
                        '$ref': '#/definitions/Categories'
                    }
                }
            },
            'required': [
                'HouseName'
            ]
        },
        'HouseCollection': {
            '$ref': '#'
        }
    },
    'type': 'object',
    'additionalProperties': false,
    'properties': {
        'houses': {
            'description': '',
            'type': 'array',
            'items': {
                '$ref': '#/definitions/House'
            }
        }
    }
}");

            string housesJsonString = JsonConvert.SerializeObject(houses);
             bool valid = false;
            JArray housesJson = JArray.Parse(housesJsonString);

            foreach (JObject s in housesJson)
            {
                IList<string> messages;
                valid = housesJson.IsValid(schema, out messages);
            }


            return valid;

How do I alter this code to call the validation method once? When I tried it it gave this error in the messages IList:

Invalid type. Expected Object but got Array. Path ", line1, position 1."

3
  • 1
    Complained ? Please post the error you saw. Why not just create a model that represents the schema, and then use generics to deserialize your json into a typed collection? Taking advantage of the typing system would greatly improve your velocity here. Commented Feb 12, 2017 at 18:23
  • @BentOnCoding I'm working on reproducing the error for "complained", sorry. Just trying to understand your suggestion. Would that involve not using a JSON schema validation package, and instead doing it manually by checking the types? Also my JSON Schema is coming from a JSON file. Can I skip the stage of converting it to a string? Thanks! Commented Feb 12, 2017 at 18:42
  • @BentOnCoding Just posted the error. Cheers Commented Feb 12, 2017 at 18:49

2 Answers 2

1

Creating an object and placing the array inside it was the solution.

var housesObject = new {
 houses = houses
};

string housesJsonString = JsonConvert.SerializeObject(housesObject);
JObject housesJson = JObject.Parse(housesJsonString);
IList < string > messages;
bool valid = housesJson.IsValid(schema, out messages);
return valid;
Sign up to request clarification or add additional context in comments.

3 Comments

First. This post/answer saved the day. Second, I had a slightly different syntax sugar. ICollection<Employee> emps = new List<Employee>(); for(int i = 0; i< 10; i++) { emps.Add(new Employee() { LastName = "LN" + i.ToString(), FirstName = "FN" + i.ToString()}); } JArray jar = JArray.FromObject(emps); JObject resultSet = JObject.FromObject(new { myRows = jar }); return req.CreateResponse(HttpStatusCode.OK , resultSet);
Thank you. You tiny tip here (the "houses" wrapper for the collection and eventual json) helped me solve doing a (what i thought was) simple "for-each". See stackoverflow.com/questions/45719964/…
@granadaCoder Glad my answer helped!
0

Modifying the foreach in your code worked for me. Posting the entire method below.

Invalid type. Expected Object but got Array. Path ", line1, position 1."

    /// <summary>
    /// This method will validate JSON schema using JSON Schema string value
    /// </summary>
    /// <param name="responseJSONValue">Response received in JSON format or a JSON value for which schema validation is to be performed</param>
    /// <param name="expectedJSONSchema">Expected JSON schema as string which need to validate against JSON value</param>
    /// <param name="messages">This will return error messages in List if validation fails</param>
    /// <returns>This method will return True or False as per JSON schema validation result</returns>
    public bool IsJSONSchemaValid(string responseJSONValue, string expectedJSONSchema, out IList<string> messages)
    {
        try
        {
            bool isSchemaValid = false;
            messages = null;
            JSchema schema = JSchema.Parse(expectedJSONSchema);

            //For JSON object - schema validation
            if (responseJSONValue.StartsWith("{") && responseJSONValue.EndsWith("}"))
            {
                JObject jObject = JObject.Parse(responseJSONValue);
                isSchemaValid = jObject.IsValid(schema, out messages);
            }

            //For JSON array - schema validation
            if (responseJSONValue.StartsWith("[") && responseJSONValue.EndsWith("]"))
            {
                JArray jArray = JArray.Parse(responseJSONValue);

                foreach (JObject currentObject in jArray)
                {
                    isSchemaValid = currentObject.IsValid(schema, out messages);

                    if (!isSchemaValid)
                    {
                        break;
                    }
                }
            }

            return isSchemaValid;
        }
        catch (Exception)
        {
            throw;
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.