I'm trying to validate the output of some REST Web API functions I've created against a third-party provided JSON schema. I'm using a .NET 4.8 console app to do the validation.
I'm using JSON.NET Schema (v3.0.0), and have been struggling with this problem here: my project-response.json
schema file looks something like this:
{
"$id": "http://www.whereever.com/services/projects/project-response.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "project response definition",
"type": "object",
"properties": {
....
"lead": {
"description": "The lead person",
"$ref": "common-types.json#/definitions/personType"
},
....
}
}
Among other things, it contains references to the common-types.json
file in the same directory, that defines some basic types used by various parts of the schema - something like this:
{
"$id": "http://www.whereever.com/services/projects/common-types.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "common type definitions",
"definitions": {
....
"personType": {
"type": "object",
"properties": {
"firstname": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"lastname": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"email": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
},
"required": [
"firstname",
"lastname"
]
},
I get a JSON string as the response from API call, and I'd like to validate this JSON against this schema. I have tried to do it like this:
public bool Validate(string jsonData)
{
string jsonSchemaFileName = Path.Combine(_schemaBaseDirectory, "project-response.json");
// define a Json Text Reader for the schema
using (StreamReader schemaFile = File.OpenText(jsonSchemaFileName))
using (JsonTextReader reader = new JsonTextReader(schemaFile))
{
JSchemaUrlResolver resolver = new JSchemaUrlResolver();
JSchemaReaderSettings settings = new JSchemaReaderSettings
{
Resolver = resolver,
BaseUri = new Uri(jsonSchemaFileName)
};
JSchema schema = JSchema.Load(jsonReader, settings);
// validate
JToken jsonToken = JObject.Parse(jsonData);
bool isValid = jsonToken.IsValid(schema, out IList<string> errors);
return isValid;
}
}
I was expecting that the JSON.NET Schema system would be able to now read the common-types.json
from the same location where the project-response.json
is located and look up the definitions in that common file - but alas, on the line
JSchema schema = JSchema.Load(jsonReader, settings);
I keep getting an error:
Newtonsoft.Json.Schema.JSchemaReaderException
HResult=0x80131500
Message=Error when resolving schema reference 'common-types.json#/definitions/projectIdType'. Path 'properties.id', line 7, position 11.Source=Newtonsoft.Json.Schema
StackTrace:
at Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ResolveDeferedSchema(DeferedSchema deferedSchema) at Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ResolveDeferedSchemas() at Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ReadRoot(JsonReader reader, Boolean resolveDeferedSchemas) at Newtonsoft.Json.Schema.JSchema.Load(JsonReader reader, JSchemaReaderSettings settings)Inner Exception 1:
WebException: The remote server returned an error: (404) Not Found.
Any ideas why this fails? Have I missed something crucial?
You will need to remove $id
, from project-response.json
because it will define the base url for $ref
. See this link.
Or use JSchemaPreloadedResolver
to preload the common-types.json
like
JSchemaPreloadedResolver resolver = new JSchemaPreloadedResolver();
using(var commontypes = File.Open(jsonSchemaCommonTypeFileName, FileMode.Open))
{
resolver.Add(new Uri("http://www.whereever.com/services/projects/common-types.json"), commontypes);
}
User contributions licensed under CC BY-SA 3.0