I have an object which contains one or more properties of type date. I would like to validate the object using the ajv json schema validator package. I could convert the properties of type date to a string by using the toISOString(). But the object can be quiet big and thus I dont want to convert all the date-properties of the whole object. Is there a solution other than converting the date to a string? Could I somehow create a custom ajv schema validator?
// My example schema
const schema = {
"properties": {
"createdAt": {
"type": "string",
"format": "date-time"
},
"lastName": { "type": "string" },
"firstName": { "type": "string" }
}
};
// My example testobject
const testObj = {
createdAt: new Date(),
lastName: "Doe",
firstName: "John"
}
// The validation
const validate = ajv.compile(schema);
const valid = validate(testObj);
if(!valid) console.log('Invalid: ' + ajv.errorsText(validate.errors));
This will do a console log, because the testObj.createdAt is a date and not a string.
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.
For example, because JSON doesn't have a “DateTime” type, dates need to be encoded as strings. format allows the schema author to indicate that the string value should be interpreted as a date. By default, format is just an annotation and does not effect validation.
This is the recommended form of date/ timestamp. date : This SHOULD be a date in the format of YYYY-MM-DD. It is recommended that you use the "date-time" format instead of "date" unless you need to transfer only the date part. time : This SHOULD be a time in the format of hh:mm:ss.
JSON Schema is a JSON-based format for defining the structure of JSON data. It provides a contract for what JSON data is required for a given application and how to interact with it. It can be used for validation, documentation, hyperlink navigation, and interaction control of JSON data.
Simply change your ajv schema from "type": "string"
to "type": "object"
and the built-in ajv date-time format will work. Here's a working fiddle.
You can also define a custom ajv format to validate a Date object (or string) like this:
ajv = new Ajv();
ajv.addFormat('custom-date-time', function(dateTimeString) {
if (typeof dateTimeString === 'object') {
dateTimeString = dateTimeString.toISOString();
}
return !isNaN(Date.parse(dateTimeString)); // any test that returns true/false
});
... and invoke your custom format in the ajv schema like this:
const schema = {
"properties": {
"createdAt": {
"type": "object",
"format": "custom-date-time"
Putting it all together here's the code and a working fiddle for creating a custom date format:
// My example schema
const schema = {
"properties": {
"createdAt": {
"type": "object",
"format": "custom-date-time"
},
"lastName": {
"type": "string"
},
"firstName": {
"type": "string"
},
"required": [ 'createdAt', 'lastName', 'firstName' ],
"additionalProperties": false,
}
};
// My example testobject
const testObj = {
createdAt: new Date(),
lastName: "Doe",
firstName: "John"
}
// The validation
ajv = new Ajv();
ajv.addFormat('custom-date-time', function(dateTimeString) {
if (typeof dateTimeString === 'object') {
dateTimeString = dateTimeString.toISOString();
}
return !isNaN(Date.parse(dateTimeString)); // return true/false
});
const validate = ajv.compile(schema);
const valid = validate(testObj);
if (valid)
alert('valid');
else
alert('Invalid: ' + ajv.errorsText(validate.errors));
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