gregsdennis/Manatee.Json

Invalid URI Exception for local references

jamlen opened this issue · 6 comments

I'm new to using Manatee and I'm trying to define local external references, but I keep getting a UriFormatException and I can't find any wiki pages or documentation to indicate how I wire this up.

Test Code:

var json = JsonValue.Parse(File.ReadAllText($@"c:\src\schema-test\schema.json"));
JsonSchemaFactory.SetDefaultSchemaVersion<JsonSchema07>();
var schema = JsonSchemaFactory.FromJson(json);
var input = JsonValue.Parse(File.ReadAllText($@"c:\src\schema-test\input.json"));
var results = schema.Validate(input);

./input.json

{
  "company": {
    "name": "string",
    "registrationNumber": "01345678",
    "companyType": "LTD",
    "vatNumber": "string",
    "sicCode": "62012"
  }
}

./schema.json

{
  "definitions": {
  },
  "type": "object",
  "properties": {
    "company": {
      "$ref": "company.json#"
    }
  }
}

./company.json

{
  "$id": "#company",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "registrationNumber": {
      "type": "string",
      "minLength": 8,
      "maxLength": 8,
      "pattern": "^(\\d{8})|SC\\d{8}$",
      "examples": [
        "06238112",
        "SC01234567"
      ]
    },
    "companyType": {
      "type": "string",
      "enum": [
        "LTD",
        "PLC",
        "LLP",
        "IPS",
        "RC",
        "UNLTD",
        "CIC",
        "LTDG"
      ]
    },
    "vatNumber": {
      "type": "string",
      "description": "A valid EU VAT Registration Number",
      "examples": [
        123456789,
        "1234 567 89",
        "GB123456789",
        "GB 1234 567 89"
      ]
    },
    "sicCode": {
      "type": "string",
      "description": "A valid UK SIC code as per http://resources.companieshouse.gov.uk/sic/",
      "pattern": "[0-9]{5}",
      "examples": [
        616,
        17230,
        42120,
        62012
      ]
    }
  },
  "required": [
    "name",
    "registrationNumber"
  ]
}

And I get the following error:

System.UriFormatException : Invalid URI: The format of the URI could not be determined.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at Manatee.Json.Schema.JsonSchemaRegistry.Get(String uri)
   at Manatee.Json.Schema.JsonSchemaReference._Resolve(JsonValue root)
   at Manatee.Json.Schema.JsonSchemaReference.Validate(JsonValue json, JsonValue root)
   at Manatee.Json.Schema.Validators.PropertiesSchemaPropertyValidatorBase`1.Validate(IJsonSchema schema, JsonValue json, JsonValue root)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Manatee.Json.Schema.JsonSchema07.Validate(JsonValue json, JsonValue root)

The only way I have managed to get it to work is to set the reference in schema.json to "$ref": "file://company.json#" and then set a Download function like this:

JsonSchemaOptions.Download = (uri) =>
{
    if (uri.StartsWith("file://")) uri = uri.Replace("file://", "");
    var text = File.ReadAllText($@"c:\src\schema-test\{uri}");
    return text;
};

Relative references in schema only work when the referring schema (schema.json in your example) has a document path defined. To do this, use JsonSchemaFactory.Load() instead of reading the text and parsing the JSON manually.

This will register the document path with the schema and then it can work out relative paths from there.

Thanks for the quick reply... I can't seem to see a Load method on JsonSchemaFactory... am I missing something?

Ah! Yes! I removed that due to redundancy with JsonSchemaRegistry.Get(). I believe that's what you're looking for. You can see it used here.

@jamlen did this resolve your issue?

lbcsy commented

Although JsonSchemaRegistry resolve this issue, but in the case there is a typo in the uri, I would rather see a message in the validation result instead of throwing an exception. Imaging a scenario in which the system can accept the user submitting their schema files and use them to validate Json files later. If the submitted schema is incorrect in one of the uris in the schema, the system won't be able to tell the user exactly which uri has issue.

Fair point. I'll look at adding that, probably as a configurable behavior.