Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON Schema validation with date fields

I'm having trouble using the JSchemaValidatingReader from the Newtonsoft.Json.Schema library. The issue is around validating date fields in JSON data.

Given this schema and data

var schemaString = "{\"type\":\"object\",\"properties\":{\"DueDate\":{\"required\":true,\"type\":\"string\",\"format\":\"date\"},\"DateCompleted\":{\"required\":true,\"type\":\"string\",\"format\":\"date-time\"}}}";
var jsonData = "{\"DueDate\":\"2015-08-25\",\"DateCompleted\":\"2015-08-27T22:40:09.3749084-05:00\"}";

I can validate the data correctly using the JToken.IsValid() method. Like this:

IList<string> errors = new List<string>();
var schema = JSchema.Parse(schemaString);
var json = JToken.Parse(jsonData);
var isValid = json.IsValid(schema, out errors); //isValid = true with no errors

However, if I try to accomplish the same thing using JSchemaValidatingReader, I get a different result.

var jsonReader = new JsonTextReader(new StringReader(jsonData));
var validatingReader = new JSchemaValidatingReader(jsonReader);
validatingReader.Schema = schema;
validatingReader.ValidationEventHandler += (o, a) => errors.Add(a.Path + ": " + a.Message);

var serializer = new JsonSerializer();
var hw = serializer.Deserialize<Homework>(validatingReader);

This will result in the error list containing an error with the message:

DueDate: String '2015-08-25T00:00:00' does not validate against format 'date'. Path 'DueDate', line 1, position 23.

Somehow the time component is being added to the date string. This error can be avoided by setting the JsonTextReader.DateFormatString property like this:

jsonReader.DateFormatString = "yyyy-MM-dd";

However, this just causes date-time fields to not validate with this error:

DateCompleted: String '2015-08-27' does not validate against format 'date-time'. Path 'DateCompleted', line 1, position 75.

Am I doing something wrong? Or is there an issue with the JSchemaValidatingReader implementation?

like image 774
Joe Camp Avatar asked Nov 21 '25 15:11

Joe Camp


1 Answers

The issue is caused by JsonTextReader + the deserializer parsing the date strings to DateTimes. Once that happens the original string is lost and the validating reader has to convert the DateTime back to a string before it can be validated. This doesn't happen with IsValid because it reads everything as a string.

Two solutions for now:

  1. Stick with validating using IsValid.
  2. On JsonTextReader set DateParseHandling to DateParseHandling.None. Dates will always be read as strings and the serializer will handle converting them to DateTime
like image 192
James Newton-King Avatar answered Nov 23 '25 05:11

James Newton-King