0

I've seen a number of questions on here already here and here but still not able to the following working.

For either of these responses which are in ex.Message:

Response 1

[
  {
    "validationErrorType": "WrongType",
    "message": "Validation error of type WrongType",
    "errorType": "ValidationError"
  }
]

Response 2

[
  {
    "message": "Validation error of type WrongType:",
    "errorType": "ValidationError"
  }
]

I am trying to dynamically parse this as follows:

JArray parsedJObject = JArray.Parse(ex.Message);

JSchema oldSchema = JSchema.Parse(@"
            {
                'type': 'array',
                'properties': {
                    'message': {'type': 'string'},
                    'errorType': {'type': 'string'}
            },
            'additionalProperties': false
            }");

JSchema graphQlSchema = JSchema.Parse(@"
            {
                'type': 'array',
                'properties': {
                    'validationErrorType': {'type': 'string'},
                    'message': {'type': 'string'},
                    'errorType': {'type': 'string'}
            },
            'additionalProperties': false
            }");

if (parsedJObject.IsValid(oldSchema)) // IsValid - 1
{
    // Do stuff
}
else if (parsedJObject.IsValid(graphQlSchema)) // IsValid - 2
{
    // Do stuff
}

However both IsValid() calls return true for either response. What am I doing wrong here?

For response 1, I'm expecting IsValid - 1 to return true and IsValid - 2 to return false

And for response 2, I'm expecting IsValid - 1 to return false and IsValid - 2 to return true

Update

Following the suggestions by David Kujawski and dbc to loop through the JArray and add the required attribute I've made progress.

My updated code is below but still struggling with validating a schema with a nested locations object.

Response

[
  {
    "validationErrorType": "WrongType",
    "locations": [
      {
        "line": 4,
        "column": 1
      }
    ],
    "message": "Validation error of type WrongType",
    "errorType": "ValidationError"
  }
]

Schema Definition:

JSchema graphQlSchema = JSchema.Parse(@"
    {
        'type': 'object',
        'properties': 
        {
            'validationErrorType': {'type': 'string'},
            'locations':           
                {
                    'type': 'object',
                    'properties': 
                    {
                        'line':   {'type': 'string'},
                        'column': {'type': 'string'}
                    }
                },
            'message':             {'type': 'string'},
            'errorType':           {'type': 'string'}
        },
        'additionalProperties': false,
        'required': ['message', 'errorType', 'validationErrorType', 'locations']
    }");

Parsing response

JArray parsedJObject = JArray.Parse(ex.Message);

foreach (JToken child in parsedJObject.Children())
{
    if (child.IsValid(graphQlSchema)) // Not resolving to true
    {
        var graphQlSchemaDef = new[] 
                        {
                            new
                            {
                                validationErrorType = string.Empty,
                                locations = new
                                    {
                                        line = string.Empty,
                                        column = string.Empty
                                    },
                                message = string.Empty,
                                errorType = string.Empty
                            }
                        };

        var exceptionMessages = JsonConvert.DeserializeAnonymousType(ex.Message, graphQlSchemaDef);

        foreach (var message in exceptionMessages)
        {
            // Do stuff
        }
    }
}
Ciaran Martin
  • 578
  • 4
  • 12
  • They are similar. only *validationErrorType* can be null – L.B Sep 05 '17 at 20:22
  • I don't understand what you mean. Can you clarify please? – Ciaran Martin Sep 05 '17 at 20:25
  • Property *validationErrorType* is a string, string is a reference type and can be *null* – Sir Rufo Sep 05 '17 at 20:28
  • A concrete class containing all 3 properties is enough. *validationErrorType* will be sometimes null. – L.B Sep 05 '17 at 20:30
  • For `graphQlSchema`, try marking `validationErrorType` as required, as shown in https://spacetelescope.github.io/understanding-json-schema/reference/object.html#required-properties. Json,NET schema seems to support this as shown by the docs: https://www.newtonsoft.com/jsonschema/help/html/P_Newtonsoft_Json_Schema_JSchema_Required.htm – dbc Sep 05 '17 at 20:34
  • Apologies for the delay in replying, but I was on holiday until today. I've made progress adding the required attribute and looping through the JArray as per David Kujawski reply. I've updated the question with the changes I've made to leave with with one issue related to nested objects. – Ciaran Martin Sep 13 '17 at 10:56

1 Answers1

2

Your issue is with the JArray vs JObject. If you really want to process ex.Message as an array, then you need to loop through the children of the array. Also, change your JsonSchema from "array" to "object". The following works as you described:

        JArray parsedJObject = JArray.Parse(ex.Message);

        JSchema oldSchema = JSchema.Parse(@"
        {
            'type': 'object',
            'properties': {
                'message': {'type': 'string'},
                'errorType': {'type': 'string'}
            },
            'additionalProperties': false
        }");

        JSchema graphQlSchema = JSchema.Parse(@"
        {
            'type': 'object',
            'properties': {
                'validationErrorType': {'type': 'string'},
                'message': {'type': 'string'},
                'errorType': {'type': 'string'}
            },
            'additionalProperties': false
        }");

        foreach (var item in parsedJObject.Children())
        {
            if (item.IsValid(oldSchema)) // IsValid - 1
            {
                // Do stuff
            }
            else if (item.IsValid(graphQlSchema)) // IsValid - 2
            {
                // Do stuff
            }
        }
David Kujawski
  • 319
  • 1
  • 7