Не могу получить JSON. NET Schema, чтобы найти мои файлы схемы JSON с внешними ссылками - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь проверить вывод некоторых функций REST Web API, которые я создал, по схеме JSON, предоставленной третьей стороной. Я использую консольное приложение. NET 4.8 для проверки.

Я использую JSON. NET Schema (v3.0.0) и борюсь с этой проблемой здесь: my project-response.json файл схемы выглядит примерно так:

{
  "$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"
    },
    ....
  }
}

Среди прочего, он содержит ссылки на файл common-types.json в том же каталоге, который определяет некоторые базовые c типы, используемые различными частями схемы - что-то вроде этого:

{
  "$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"
      ]
    }, 
    

Я получаю строку JSON в качестве ответа от вызова API, и я хотел бы проверить это JSON на соответствие этой схеме. Я пытался сделать это так:

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;
    }
}

Я ожидал, что система JSON. NET Schema сможет теперь читать common-types.json из того же места, где project-response.json находится и найдите определения в этом общем файле - но, увы, в строке

JSchema schema = JSchema.Load(jsonReader, settings);

Я все время получаю сообщение об ошибке:

Newtonsoft. Json .Schema .JSchemaReaderException HResult = 0x80131500 Сообщение = Ошибка при разрешении ссылки на схему 'common-types.json # / definitions / projectIdType'. Путь 'properties.id', строка 7, позиция 11.

Source = Newtonsoft. Json .Schema

StackTrace: в Newtonsoft. Json .Schema.Infrastructure.JSchemaReader.ResolveDeferSchema (DeferSchema deferSchema) в Newtonsoft. Json .Schema.Infrastructure.JSchemaReader.ResolveDeferSchemas () в Newtonsoftchema. Json. * (Читатель JsonReader, Boolean resolveDeferSchemas) в Newtonsoft. Json .Schema.JSchema.Load (Читатель JsonReader, настройки JSchemaReaderSettings)

Внутреннее исключение 1: WebException: удаленный сервер возвратил ошибку: (404) Not Found.

Есть идеи, почему это не удается? Я что-то важное упустил?

1 Ответ

1 голос
/ 13 июля 2020

Вам нужно будет удалить $id из project-response.json, потому что он будет определять базовый URL для $ref. См. Эту ссылку . Или используйте JSchemaPreloadedResolver, чтобы предварительно загрузить common-types.json, например

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...