Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique Keys Validation not Working? #181

Closed
ryderjgillen opened this issue Nov 13, 2021 · 12 comments · Fixed by #182
Closed

Unique Keys Validation not Working? #181

ryderjgillen opened this issue Nov 13, 2021 · 12 comments · Fixed by #182
Labels
question Further information is requested

Comments

@ryderjgillen
Copy link

ryderjgillen commented Nov 13, 2021

Environment

  • Nuget Package: JsonSchema.Net.UniqueKeys 1.0.0
  • OS: Windows 11
  • .Net Target: net5.0

How can I help you today?
The JSON schema validation for unique keys does not seem to work (or I am missing something)

Following example: https://gregsdennis.github.io/json-everything/usage/vocabs-unique-keys.html

Additional context

Schema

{
  "$schema": "https://gregsdennis.github.io/json-everything/meta/unique-path",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "foo": { "type": "integer" }
    }
  },
  "uniqueKeys": [
    "/foo"
  ]
}

Input

[
  { "foo": 8 },
  { "foo": 12 },
  { "foo": 42 }
]

Example

  var s = JsonSchema.FromFile("schema.json");
  var d = System.Text.Json.JsonDocument.Parse(File.ReadAllText("input.json"));
  var r = s.Validate(d.RootElement);

  Console.WriteLine(JsonSerializer.Serialize(r));

Output

{"valid":false,"keywordLocation":"#","instanceLocation":"#"}

@ryderjgillen ryderjgillen added the question Further information is requested label Nov 13, 2021
@gregsdennis
Copy link
Owner

gregsdennis commented Nov 13, 2021

Looks like my example is wrong. The docs day that the correct URI for the vocab is https://gregsdennis.github.io/json-everything/vocabs-unique-keys. Update $schema to that, and it should work.

@ryderjgillen
Copy link
Author

Still no dice... I had a look at the Unit Tests in the project and found this line in the test setup
Json.Schema.UniqueKeys.Vocabularies.Register();

If I add that to my code I get the following error during Schema Load

Could not load type 'Json.Pointer.JsonPointer' from assembly 'JsonSchema.Net.UniqueKeys, Version=1.0.0.0

@gregsdennis
Copy link
Owner

What versions of JsonSchema.Net and JsonPointer.Net are you using?

@ryderjgillen
Copy link
Author

ryderjgillen commented Nov 13, 2021

JsonSchema.Net - 1.11.5
JsonSchema.Net.UniqueKeys - 1.0.0
JsonPointer.Net - 2.0.0 (indirect reference)

@gregsdennis
Copy link
Owner

gregsdennis commented Nov 13, 2021

I may need to release a new version of unique-keys to reference 2.0 on pointers. I can do that tonight.

@ryderjgillen
Copy link
Author

Ok great thanks!

I tried downgrading to 1.11.4 which references JsonPointer.Net 1.4.0

Now I get a different error: System.Text.Json.JsonException: 'Expected object'

So I am not sure if that will fix it or something else is going on.

@gregsdennis
Copy link
Owner

gregsdennis commented Nov 13, 2021

@sacvalleytech your example works fine on https://json-everything.net/json-schema, which is using the latest of all of the packages and running .net 5.

Without the vocabulary registration, I get the same you did at first. With the registration, I get:

{
  "valid": true,
  "keywordLocation": "#",
  "instanceLocation": "#",
  "annotations": [
    {
      "valid": true,
      "keywordLocation": "#/$schema",
      "instanceLocation": "#"
    },
    {
      "valid": true,
      "keywordLocation": "#/type",
      "instanceLocation": "#"
    },
    {
      "valid": true,
      "keywordLocation": "#/items",
      "instanceLocation": "#",
      "annotation": true
    }
  ]
}

Here's my attempt to replicate your issue. Let me know how it runs for you.

@ryderjgillen
Copy link
Author

Interesting... its fails/succeeds based on the order of the line Json.Schema.UniqueKeys.Vocabularies.Register();

Works

var schema = JsonSchema.FromText(schemaText);
var instance = JsonDocument.Parse(instanceText).RootElement;

Json.Schema.UniqueKeys.Vocabularies.Register();
ValidationOptions.Default.OutputFormat = OutputFormat.Verbose;

Fails

Json.Schema.UniqueKeys.Vocabularies.Register();
ValidationOptions.Default.OutputFormat = OutputFormat.Verbose;

var schema = JsonSchema.FromText(schemaText);
var instance = JsonDocument.Parse(instanceText).RootElement;

@gregsdennis
Copy link
Owner

Well that is a peculiar result. Good find. I'll play with it and release a fix when I can.

Are you unblocked for now?

@ryderjgillen
Copy link
Author

Yes I can work around that... thanks for the help!

@ryderjgillen
Copy link
Author

ryderjgillen commented Nov 13, 2021

I tried cloning the repo and created the same test console app... but referenced the projects directly (instead of NuGet). The error is gone now... so it does seem to be some sort of dependency issue with the NuGet packages.

Update
I took it a step further and added the reference to NuGet package JsonSchema.Net 1.11.5 back... I copied the code from the UniqueKeys code to a new class library and referenced that instead; the UniqueKeys dependencies are also referenced via Nuget.

So it really does look like the UniqueKeys NuGet package is the culprit.

ConsoleApp.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
	  <OutputType>Exe</OutputType>
	  <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="JsonSchema.Net" Version="1.11.5" />
    <!--<PackageReference Include="JsonSchema.Net.UniqueKeys" Version="1.0.0" />-->
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\UniqueKeys\UniqueKeys.csproj" />
  </ItemGroup>

UniqueKeys.csproj

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>netstandard2.0</TargetFramework>
		<LangVersion>latest</LangVersion>
		<Nullable>enable</Nullable>
	</PropertyGroup>

	<ItemGroup>
	  <PackageReference Include="Json.More.Net" Version="1.4.4" />
	  <PackageReference Include="JsonSchema.Net" Version="1.11.5" />
	</ItemGroup>

</Project>

@gregsdennis
Copy link
Owner

I did an update of the nuget package and imported from a local nuget repo (just a folder on my disk). That seemed to fix the problem. I'm releasing new versions of all of the dependent packges (which is basically all of them).

A long time ago, I had done some work playing around with the different versions and how they interoperate with nuget packaging. I wrote a blog post about it. To my surprise, this became the general approach for most people after Jon Skeet found it and referenced it in a blog post of his own when he was updating NodaTime to v2. (In fact, MS now highlights this approach in their docs, but they don't reference my post.)

According to that approach, I should have released new major versions of everything.

A few months ago, I discovered that starting with .Net Core 3.1, it seemed that the framework didn't care anymore about the version attributes in the assembly file because I was able to reference new major versions without having to rebuild dependent assemblies. As a result, when I updated JsonPointer.Net, I figured I'd be fine by just releasing a patch version update of the direct dependencies.

It seems that there's still an issue with downstream dependencies, though. I guess I should just stick with the approach I laid out before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants