Code Monkey home page Code Monkey logo

newtonsoft.json.schema's Introduction

newtonsoft.json.schema's People

Contributors

ggirard07 avatar jamesnk avatar jonhanna avatar jorrit avatar kant2002 avatar kevin-secrist avatar kunlinyu avatar nzsmartie avatar raidenyn avatar tbotv63 avatar vaevictus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

newtonsoft.json.schema's Issues

Calling ToString on a JSchema object does not fully expand all references

I am running into issues when I try to get a string representation of a JSchema when the schema file it was created from contains multiple of the same reference.

For example, suppose I have a definitions.json file:

{
  "$schema": "http://json-schema.org/draft-04/hyper-schema#",
  "sampleValue": {
    "title": "This is a sample value",
    "type": "string",
  },
  "sampleValueContainer": {
    "title": "This holds an item of sample value",
    "type": "object",
    "properties": {
      "value": {"$ref": "#/sampleValue"},
    }
  }
}

and a test_object.json file

{
  "$schema": "http://json-schema.org/draft-04/hyper-schema#",
  "title": "Test Object",
  "type": "object",
  "properties": {
    "container": { "$ref": "/definitions.json#/sampleValueContainer" },
    "value": { "$ref": "/definitions.json#/sampleValue"}
  }
}

Since sampleValueContainer includes a sampleValue, the test_object schema references sampleValue twice. However, when I load test_object.json into a JSchema object and call ToString, I get the following output:

{
  "title": "Test Object",
  "type": "object",
  "properties": {
    "container": {
      "title": "This holds an item of sample value",
      "type": "object",
      "properties": {
        "value": {
          "title": "This is a sample value",
          "type": "string"
        }
      }
    },
    "value": {
      "$ref": "#/properties/container/properties/value"
    }
  }
}

The value field, rather than being expanded out into the sampleValue subschema, is just replaced with an internal reference. For what I am doing it's important that the string I produce contain no internal or external references.

Is this replacement functionality intended? I haven't been able to find documentation related to the replacement of an external ref with an internal ref, nor have I been able to find a way to easily expand internal references in the JSchemas.

Thanks!

Could not resolve schema reference of this type: 'schema.json/#address'

Hi,

I'm getting 'Could not resolve schema reference 'schema.json/#address'"' error when I tried to resolve the reference of the schema that is present in other file. Please look into this.

Here is the code to load the jsonschema:

resolver.Add(new Uri("schema.json", UriKind.RelativeOrAbsolute),new FileStream("schema.json",FileMode.Open));
JSchema sampleSchema = JSchema.Parse(@"{
'type': 'object',
'allOf': [
{ '$ref': 'schema.json#address' }
],
}", resolver);

Here is schema.json file that i'm referring to
{
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
}
}

Please fix it.Thank you.

V4 validation issue

From JamesNK/Newtonsoft.Json#115 (comment)

Hi James,

I've been doing some tests on the new v4 schema validation support and I come across an issue. I'm sending JSON request to a well known web portal. As part of their client validation process they provide a set of v4 schemas for the various request types they support and an valid example of each of the JSON requests so that users of their API can perform some sanity checks.
When I run their test requests through my code using Json.NET some of the requests fail validation.

The portal says they have run the sample through http://json-schema-validator.herokuapp.com and
and https://github.com/Julian/jsonschema . Both report no errors. I've included below both the v4 schema and the test JSON request. This is the smallest request and schema that failed. Json.Net reported the validation error in the errorList as:
"JSON is valid against more than oneschema from 'oneOf'. Valid schema indexes: 0, 1. Line 1, position 1.

JSON Request:

{
"branch_reference" : "zpg_test_1",
"branch_name" : "XXX Test Branch",
"location" : {
"property_number_or_name" : "65",
"street_name" : "Some Street",
"town_or_city" : "London",
"postal_code" : "SEX 0HR",
"country_code" : "GB"
},
"email": "[email protected]",
"website" : "http://www.xxx.co.uk/"
}

V4 Schema:

{
"$schema" : "http://json-schema.org/draft-04/schema#",
"title" : "branch/update",
"type" : "object",
"additionalProperties" : false,
"id" : "http://realtime-listings.webservices.xxx.co.uk/docs/v0.1/schemas/branch/update.json",
"definitions" : {
"coordinates" : {
"type" : "object",
"additionalProperties" : false,
"properties" : {
"latitude" : {
"type" : "number",
"minimum" : -90,
"maximum" : 90
},
"longitude" : {
"type" : "number",
"minimum" : -180,
"maximum" : 180
}
},
"required" : [
"latitude",
"longitude"
]
}
},
"properties" : {
"branch_name" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)\S)\Z"
},
"branch_reference" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)
\S)\Z"
},
"email" : {
"type" : "string",
"pattern" : "@"
},
"location" : {
"type" : "object",
"additionalProperties" : false,
"properties" : {
"property_number_or_name" : {
"type" : [
"integer",
"string"
],
"pattern" : "^\S(|(.|\n)\S)\Z"
},
"street_name" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)
\S)\Z"
},
"locality" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)\S)\Z"
},
"town_or_city" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)
\S)\Z"
},
"county" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)\S)\Z"
},
"postal_code" : {
"type" : "string",
"pattern" : "^\S(|(.|\n)
\S)\Z"
},
"country_code" : {
"type" : "string",
"pattern" : "^[A-Z]{2}(-[A-Z0-9]{1,3})?$"
},
"coordinates" : {
"$ref" : "#/definitions/coordinates"
},
"paf_address" : {
"type" : "object",
"additionalProperties" : false,
"properties" : {
"address_key" : {
"type" : "string",
"pattern" : "^[0-9]{8}$"
},
"organisation_key" : {
"type" : "string",
"pattern" : "^[0-9]{8}$"
},
"postcode_type" : {
"enum" : [
"L",
"S"
]
}
},
"required" : [
"address_key",
"organisation_key",
"postcode_type"
]
},
"paf_udprn" : {
"type" : "string",
"pattern" : "^[0-9]{8}$"
}
},
"required" : [
"street_name",
"town_or_city",
"country_code"
]
},
"telephone": {
"type" : "string",
"pattern" : "[0-9]+"
},
"website" : {
"type" : "string",
"pattern" : "^[Hh][Tt][Tt][Pp][Ss]?://\S+$"
}
},
"required" : [
"branch_reference",
"branch_name",
"location"
],
"oneOf" : [
{ "$ref" : "#/constraints/gb" },
{ "$ref" : "#/constraints/overseas" }
],
"constraints" : {
"gb" : {
"properties" : {
"location" : {
"properties" : {
"country_code" : {
"pattern" : "^GB"
},
"postal_code" : {
"pattern" : "^[A-PR-UWYZ][A-HJ-Y]?[0-9][0-9A-HJKMNPR-Y]? [0-9][ABD-HJLNP-UW-Z]{2}$"
}
},
"required" : [
"postal_code"
]
}
}
},
"overseas" : {
"properties" : {
"location" : {
"properties" : {
"country_code" : {
"not" : {
"pattern" : "^GB"
}
}
}
}
}
}
}
}

Generating schema for self-referencing abstract types

Right now, JSchemaGenerator generates schema for abstract types as if they are normal types: JSchemaGenerator simpy enumerates its properties.

It would be better if the generated schema somehow accounted for the possibility of the value to be one of the descendants of the abstract type.

For example, I have a Dictionary<string, BlockBase> and I want the corresponding json object to consist of the properties with the values of BlockBase descendants and only of them. Also I want all the complex machinery of json validation to "propagate inside" those descendant classes and their properties.

As if it's not complicated enough, in my case I want the property names (a string in that dictionary) to determine the type of the object. And not just property names, but property name regex patterns. I did try to implement just this using a JSchemaGenerationProvider, and it almost worked, but it seems that JSchemaGenerationProvider doesn't give me an ability to work with circular "references".

Here's what I mean by "circular references". Below is my simplified structure and the implementation of JSchemaGenerationProvider that never stops being called.

internal class MyRootJsonClass
{
    public Dictionary<string, BlockBase> Blocks { get; set; }
}

internal abstract class BlockBase
{
    // Removed from sample: a hundred of other properties

    public Dictionary<string, BlockBase> NestedBlocks { get; set; }
}

// Removed from sample: a hundred descendants of BlockBase

internal class MyJSchemaGenerationProvider : JSchemaGenerationProvider
{
    public override JSchema GetSchema(JSchemaTypeGenerationContext context)
    {
        var schema = new JSchema();
        var descendants = Assembly.GetExecutingAssembly().GetTypes().Where(item => !item.IsAbstract && typeof(BlockBase).IsAssignableFrom(item)).ToList();
        foreach (var descendant in descendants)
        {
            // The line below never exits, because it's calling MySchemaGenerator.GetSchema again with the same parameter
            var descendantSchema = context.Generator.Generate(descendant);
            schema.PatternProperties.Add(descendant.Name + ".*", descendantSchema);
        }
        schema.AllowAdditionalProperties = false;
        schema.Type = JSchemaType.Object;
        return schema;
    }

    public override bool CanGenerateSchema(JSchemaTypeGenerationContext context)
    {
        return context.ObjectType == typeof(Dictionary<string, BlockBase>);
    }
}

The "endless cycle" can be kinda solved with introducing some fields to my class and somehow caching values in them (to get only the first "level of recursion"), but it would not be a complete solution to the problem.

Summary

So, either I'm not really bright, or Newtonsoft.Json.Schema needs some mechanism to overcome these kinds of "circular references" when generating schemas.
Also, it would be great if adding support of generating schema for abstract types would be a little more straightforward.

Sorry for a long read. I'll be happy to clarify.

VS 2015 Intillisense Failing with Invalid Program Exception

I have i created a very simple console app for test purpose. It just as a two public classes,

  1. Person class
  2. Utils Class
    Person class has noting but few properties like, name, age, address etc
    Utils class has only one public static method ConverToJson which get persons instance and return Newtonsoft.Json.JsonConvert.SerializeObject(item);
  3. Program.cs has main function, which just creates the object of person with some dummy data and use utils.ConverToJson to dump the output on screen.

Now the problem,
One Utils class i used VS2015 RTM's feature of create IntillTest, it created a new project with a TestFixture class of PEX, falour, which contains parameterized unit tests for Utils class, when i run the tests i get below exception

ystem.InvalidProgramException: Common Language Runtime detected an invalid program. at System.Void Newtonsoft.Json.JsonSerializer..ctor()
at Newtonsoft.Json.JsonSerializer Newtonsoft.Json.JsonSerializer.Create()
at Newtonsoft.Json.JsonSerializer Newtonsoft.Json.JsonSerializer.Create(Newtonsoft.Json.JsonSerializerSettings settings)
at Newtonsoft.Json.JsonSerializer Newtonsoft.Json.JsonSerializer.CreateDefault()
at Newtonsoft.Json.JsonSerializer Newtonsoft.Json.JsonSerializer.CreateDefault(Newtonsoft.Json.JsonSerializerSettings settings)
at System.String Newtonsoft.Json.JsonConvert.SerializeObject(System.Object value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings)
at System.String Newtonsoft.Json.JsonConvert.SerializeObject(System.Object value)
C:\Projects\TestProjects\Json_IntilliTest\Json_IntilliTest\Utils.cs(14): at System.String Json_IntilliTest.Utils.ConvertToJson(Json_IntilliTest.Person item)
C:\Projects\TestProjects\Json_IntilliTest\Json_IntilliTest.Tests\UtilsTest.cs(21): at System.String Json_IntilliTest.Tests.UtilsTest.ConvertToJsonTest(Json_IntilliTest.Person item)

Cannot generate schema of type that uses [JsonConverter] class attribute

I am having a weird problem where I cant generate a schema for some of my dto classes.

any classes that derive from an abstract class that is decorated with [JsonConverter(MyCustomConverter)] fail without an exception. The schema generated is {{}}
I use the JSONConverter to control the deserialization of json objects posted to my web api from my clients, and I dont see how this should be intefering of generating the schema from the type.

Any ideas?

ItemsPositionValidation needs to be set manually

Hi

I am creating a schema manually.

var schema = new JSchema
{
    Type = JSchemaType.Boolean
};

schema.ExtensionData.Add("name","name");

schema.Properties.Add(new KeyValuePair<string, JSchema>("field1",new JSchema
{
    Type = JSchemaType.Array,

}));

schema.Properties["field1"].Items.Add(
    new JSchema
    {
        Type = JSchemaType.String
    });

schema.Properties["field1"].Items.Add(
   new JSchema
   {
       Type = JSchemaType.Boolean
   });

schema.Properties["field1"].ItemsPositionValidation = true;

When i dont set ItemsPositionValidation =true and i tostring the schema it only returns one item.

Now i sort of get the idea that creating a schema manually is not really the way this was intendant i should rather load from json so that all internals can kick in but i thought i just mention it.

thanks

compile from source

how can i compile the current version? during my tinkering i've learned about friend assemblies which was nice :) but i didn't manage to resolve lots of the compiler errors. can you point me in the right direction?

i'm really excited about the new ResolveSchemaContext but as said, i couldn't get it to work.

Refs to "#" don't parse from a common definition

I have a schema that has a 'manager' property which is a user object:

"manager": {
  "anyOf": [{
    "$ref": "#/definitions/user"
  }],
  "title": "Manager"
}

The #/definitions/user schema is:

"definitions": {
  "user": {
    "$ref": "#"
  }
}

This results in a "Error when resolving schema reference '#'. Path 'definitions.user'" error.

Addressing the user with "$ref": "#" from the manager property isn't an option as we are using the definition to help build the UI and need a common definition.

Download Package From Nuget Uses old Newtonsoft.Json.Schema

I downloaded the package using nuget and since Netwonsoft.Json is a dependency it downloads that as well. Since both packages have a namespace called Newtonsoft.Json.Schema, when I reference it in my code, it uses the namespace of Newtonsoft.Json.Schema contained in the Netwonsoft.Json package and not from the Newtonsoft.Json.Schema package.

So I can't validate using json schema version 4. Any ideas how to reference the proper assembly?

I also made a stackoverflow question.

Easy way to add '$ref' to Schema

Hi,

I'm using your library, to create Json schema files automatically to all our DTO classes. I wasn't really amazed about using Data Annotations mixed with [JsonProperty] attributes, so I'm doing it via reflection myself. I'm building the schema, by using the JSchema class and everything works fine. The one thing I'm missing is, to add a reference '$ref', to the other schema files, somehow to the schema. I cannot find any properties og functions from the specs from JSchema and I want to avoid, using a resolver, due to the build order of the schemas won't take care about the referencing inside the schemas. Can you help me out ?

Kind regards
Kristian

NuGet package install for UWP app

I am trying to use the schema NuGet package in a UWP project and when I run the install (Install-Package NewtonSoft.Json.Schema) I am getting the following output:

`Install-Package : System.Security.Cryptography.Csp 4.0.0 provides a compile-time reference assembly for System.Security.Cryptography.Csp on UAP,Version=v10.0, but there is no run-time assembly compatible with win10-arm.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : One or more packages are incompatible with UAP,Version=v10.0 (win10-arm).
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : System.Security.Cryptography.Csp 4.0.0 provides a compile-time reference assembly for System.Security.Cryptography.Csp on UAP,Version=v10.0, but there is no run-time assembly compatible with win10-arm-aot.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : One or more packages are incompatible with UAP,Version=v10.0 (win10-arm-aot).
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : System.Security.Cryptography.Csp 4.0.0 provides a compile-time reference assembly for System.Security.Cryptography.Csp on UAP,Version=v10.0, but there is no run-time assembly compatible with win10-x64.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : One or more packages are incompatible with UAP,Version=v10.0 (win10-x64).
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : System.Security.Cryptography.Csp 4.0.0 provides a compile-time reference assembly for System.Security.Cryptography.Csp on UAP,Version=v10.0, but there is no run-time assembly compatible with win10-x64-aot.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : One or more packages are incompatible with UAP,Version=v10.0 (win10-x64-aot).
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : System.Security.Cryptography.Csp 4.0.0 provides a compile-time reference assembly for System.Security.Cryptography.Csp on UAP,Version=v10.0, but there is no run-time assembly compatible with win10-x86.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : One or more packages are incompatible with UAP,Version=v10.0 (win10-x86).
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : System.Security.Cryptography.Csp 4.0.0 provides a compile-time reference assembly for System.Security.Cryptography.Csp on UAP,Version=v10.0, but there is no run-time assembly compatible with win10-x86-aot.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Install-Package : One or more packages are incompatible with UAP,Version=v10.0 (win10-x86-aot).
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
    
    

Package restore failed for 'TaskList.Model'.
Install-Package : Package restore failed. Rolling back package changes for 'TaskList.Model'.
At line:1 char:1

  • Install-Package NewtonSoft.Json.Schema -ProjectName TaskList.Model
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand`
    
    

Any help would be appreciated

Quota Limit checker does not reset

Have requested to purchase a license soon, but in the meantime while working on a prototype, I keep running into the quota limit.

Could there be an issue with the counter for the generator? Calling the generate method after more than an hour yields the same error.

The free-quota limit of 10 schema generations per hour has been reached. Please visit http://www.newtonsoft.com/jsonschema to upgrade to a commercial license.

I did wonder if the schema itself causes the generator to call the generate method more than 10 times.
I implemented a custom JSchemaGenerationProvider that handles the format if the property is of a certain type, but I do get the quota message prior to hitting a breakpoint in the overridden GetSchema method.

JsonObject to JSchema

I have loaded a swagger file (eg http://petstore.swagger.io/v2/swagger.json) into a JsonObject which contains json schema definitions for the return types.
The return schema of say [GET]/pet/{petId} is "#/definitions/Pet", what is the best way to turn those JsonObjects into JSchema versions. Those schemas can also contain Json pointers (see "Pet") so I'm not sure if loading from a JTokenReader is going to work?

No way to discern $ref-sourced properties from inline ones

I poked around and it looks like the Properties are populated from a $ref when parsing the schema and that reference is then dismissed.

Is there any way to tell that these properties:

"properties": { "billing_address": { "$ref": "#/definitions/address" }, "shipping_address": { "$ref": "#/definitions/address" } }

are of the same type after the schema is parsed?

Doesn't work in ASP.NET 5 on Linux

When I try to load a schema from a file in an ASP.NET 5 on Linux using File.OpenText and JsonTextReader, I get MethodAccessExceptions against JsonReaderException.Create.

This is using 1.0.4 from NuGet via kpm.

What's really confusing is that, looking at the code, the conditions that are causing the exception shouldn't even be true, in that in my own code I can run this part:

if (reader.TokenType == JsonToken.None || reader.TokenType == JsonToken.Comment)
{
    if (!reader.Read())
        throw JsonReaderException.Create(reader, "Error reading schema from JsonReader.");
}

if (reader.TokenType != JsonToken.StartObject)
    throw JsonReaderException.Create(reader, "Unexpected token encountered when reading schema. Expected StartObject, got {0}.");

At the first go, obviously with a new JsonTextReader, TokenType is None so it does the read and then it's StartObject, so everything should be fine.

I've tried pulling the source for Newtonsoft.Json and Newtonsoft.Json.Schema into my project, but obviously that's just absolute hell and nothing works because it says it can't find BigInteger, IXmlSerializable, SqlString and just about every other type in the sodding BCL.

JSchemaResolver async?

I think would be very useful have the overload on interface JSchemaResolver:

public abstract Task<Stream> GetSchemaResourceAsync(ResolveSchemaContext context, SchemaReference reference);

What do you guys think?

Potential thread safe issue?

We have a bit of code that parallelizes some validations on a large collection of objects.

Like this (ruleSchema is a JSchema object and there is only one of them):

// calc how parallel 
var opts = new ParallelOptions
{
    MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount*0.75)*1.0))
};

Parallel.ForEach(response.Entries.Cast<SearchResultEntry>(), opts, sre =>
{
    var user = new User(sre);

    var errors = this.CheckUser(user, ruleSchema);

    if (errors.Count > 0)
    {
        // do stuff
    }
    else if (generateSuccessfulUserAuditResults)
    {
        // do other stuff
    }

});

CheckUser does the JSON Schema validation and looks like this:

private IList<ValidationError> CheckUser(User user, JSchema ruleSchema)
{
    IList<ValidationError> errors = new List<ValidationError>();

    var userToCheck = user.ToJson();
    bool valid = userToCheck.IsValid(ruleSchema, out errors);

    return errors;
}

In some circumstances (very infrequently) we have seen this:

 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource):16
 System.Collections.Generic.List`1+Enumerator.MoveNextRare():19
 System.Collections.Generic.List`1+Enumerator.MoveNext():72
 System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate):71
 Newtonsoft.Json.Schema.Infrastructure.Validation.Validator.PopulateSchemaId(ValidationError error):36
 Newtonsoft.Json.Schema.Infrastructure.Validation.Validator.RaiseError(ValidationError error):104
 Newtonsoft.Json.Schema.Infrastructure.Validation.ValidatorContext.RaiseError(IFormattable message, ErrorType errorType, JSchema schema, Object value, IList`1 childErrors):7
 Newtonsoft.Json.Schema.Infrastructure.Validation.SchemaScope.RaiseError(IFormattable message, ErrorType errorType, JSchema schema, Object value, IList`1 childErrors):7
 Newtonsoft.Json.Schema.Infrastructure.Validation.ObjectScope.EvaluateTokenCore(JsonToken token, Object value, Int32 depth):86
 Newtonsoft.Json.Schema.Infrastructure.Validation.Validator.ValidateCurrentToken(JsonToken token, Object value, Int32 depth):116
 Newtonsoft.Json.Schema.JSchemaValidatingReader.ValidateCurrentToken():170
 Newtonsoft.Json.Schema.JSchemaValidatingReader.Read():15
 Newtonsoft.Json.Schema.SchemaExtensions.Validate(JToken source, JSchema schema, SchemaValidationEventHandler validationEventHandler):51
 Newtonsoft.Json.Schema.SchemaExtensions.IsValid(JToken source, JSchema schema, IList`1& errors):31
 Antrea.Windows.Shared.Workers.Audit.AdWorker.CheckUser(User user, JSchema ruleSchema) in C:\Users\chris\Documents\Projects\antrea-windows\antrea-windows-shared\Workers\Audit\AdWorker.cs:334
 Antrea.Windows.Shared.Workers.Audit.AdWorker+<>c__DisplayClass17_0.<Audit>b__0(SearchResultEntry sre) in C:\Users\chris\Documents\Projects\antrea-windows\antrea-windows-shared\Workers\Audit\AdWorker.cs:248
 System.Threading.Tasks.Parallel+<>c__DisplayClass27`2.<PartitionerForEachWorker>b__29():726
 System.Threading.Tasks.Task.InnerInvoke():15
 System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask):0
 System.Threading.Tasks.Task+<>c__DisplayClass0.<ExecuteSelfReplicating>b__1(Object ):134

Could this be threadsafe issue in PopulateSchemaId?

Uri schemaId = Schema.KnownSchemas.Single(s => s.Schema == error.Schema).Id;

Custom JSchemaGenerationProvider does not run on all nodes.

When I write a custom JSchemaGenerationProvider, it only modifies the parent node, whereas the example in the documentation indicates that it should run on every node. In this specific example, I am trying to add a title attribute to every node.

class User {
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreatedDate { get; set; }
}

class TitleProvider : JSchemaGenerationProvider {
    public override JSchema GetSchema(JSchemaTypeGenerationContext context) {
        var schema = new JSchemaGenerator().Generate(context.ObjectType);
        schema.Title = "foo";
        return schema;
    }
}

public class Program {
    public static void Main() {
        var generator = new JSchemaGenerator();
        generator.GenerationProviders.Add(new TitleProvider());
        var schema = generator.Generate(typeof(User));

        Console.WriteLine(schema);
    }
}
// OUTPUT:
//{
//  "title": "foo",
//  "type": "object",
//  "properties": {
//    "Id": {
//      "type": "integer"
//    },
//    "Name": {
//      "type": [
//        "string",
//        "null"
//      ]
//    },
//    "CreatedDate": {
//      "type": "string"
//    }
//  },
//  "required": [
//    "Id",
//    "Name",
//    "CreatedDate"
//  ]
//}

Other Notes:

  • if I return null from the TitleProvider GetSchema method, it does iterate over all the properties (which I observed in debugger), but then it's not adding a title. But it skips the child nodes (in debugger) when I return a JSchema.

Validation errors from JSON that is valid.

Hello,

I am getting validation errors from JSON that as far as I can tell is valid. I am using the JSchemaValidatingReader and JSchemaGenerator as documented.

Here is my example data:

[
  {
    "Body": "{\"Data\":\"123\",\"Timestamp\":\"2015-01-01T05:00:00Z\"}",
    "IsBodyBase64": false,
    "BrokerProperties": null,
    "UserProperties": {
      "DSP-Type": "TimestampedEventSeries",
      "DSP-Id": "ca9aa96a-5ffc-4177-af09-283180183fac"
    }
  },
  {
    "Body": "{\"Data\":\"456\",\"Timestamp\":\"2015-01-02T05:00:00Z\"}",
    "IsBodyBase64": false,
    "BrokerProperties": null,
    "UserProperties": {
      "DSP-Type": "TimestampedEventSeries",
      "DSP-Id": "ca9aa96a-5ffc-4177-af09-283180183fac"
    }
  }
]

Here is the schema that is generated from my type:

{
  "definitions": {
    "HttpBrokeredMessage": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "Body": {
          "type": [
            "string",
            "null"
          ]
        },
        "BrokerProperties": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": {
            "type": [
              "object",
              "null"
            ]
          }
        },
        "IsBodyBase64": {
          "type": "boolean"
        },
        "UserProperties": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": {
            "$ref": "#/definitions/HttpBrokeredMessage/properties/BrokerProperties/additionalProperties"
          }
        }
      }
    },
    "Object": {
      "$ref": "#/definitions/HttpBrokeredMessage/properties/BrokerProperties/additionalProperties"
    }
  },
  "type": "array",
  "items": {
    "$ref": "#/definitions/HttpBrokeredMessage"
  }
}

Here is the type definition:

        [DataContract]
        public class HttpBrokeredMessage
        {
            [DataMember]
            public string Body { get; set; }

            [DataMember]
            public Dictionary<string, object> BrokerProperties { get; set; }

            [DataMember]
            public bool IsBodyBase64 { get; set; }

            [DataMember]
            public Dictionary<string, object> UserProperties { get; set; }
        }

Here is the code I am using to deserlialize the type and sample data:

            var textReader = new StringReader(json);
            using (var jsonReader = new JsonTextReader(textReader))
            {
                using (var validatingReader = new JSchemaValidatingReader(jsonReader))
                {
                    var validationErrors = new List<string>();

                    var schemaGenerator = new JSchemaGenerator();
                    var schema = schemaGenerator.Generate(typeof(HttpBrokeredMessage[]));

                    validatingReader.Schema = schema;
                    validatingReader.ValidationEventHandler += (o, error) => { validationErrors.Add(error.Message); };

                    var serializer = new Newtonsoft.Json.JsonSerializer();
                    test = serializer.Deserialize<HttpBrokeredMessage[]>(validatingReader);

                    foreach (var error in validationErrors)
                    {
                        Console.WriteLine("=> error! " + error);
                    }
                }
            }

            foreach (var t in test)
            {
                Console.WriteLine(t.Body);
                foreach (var kvp in t.UserProperties)
                {
                    Console.WriteLine(kvp.Key + " = " + kvp.Value);
                }
            }

The ouput I get from my code is the following:

=> error! Invalid type. Expected Object, Null but got String. Path '[0].UserProperties.DSP-Type', line 7, position 44.
=> error! Invalid type. Expected Object, Null but got String. Path '[0].UserProperties.DSP-Id', line 8, position 56.
=> error! Invalid type. Expected Object, Null but got String. Path '[1].UserProperties.DSP-Type', line 16, position 44.
=> error! Invalid type. Expected Object, Null but got String. Path '[1].UserProperties.DSP-Id', line 17, position 56.
{"Data":"123","Timestamp":"2015-01-01T05:00:00Z"}
DSP-Type = TimestampedEventSeries
DSP-Id = ca9aa96a-5ffc-4177-af09-283180183fac
{"Data":"456","Timestamp":"2015-01-02T05:00:00Z"}
DSP-Type = TimestampedEventSeries
DSP-Id = ca9aa96a-5ffc-4177-af09-283180183fac

As you can see there are validation errors that are generated, however the data seems to be correctly deserialized into my type. I do not really understand why I am seeing those errors, as the UserProperties is an object, but the schema does not define child elements within that object that should be objects.

Thanks!

Need the way to mark a property as NOT REQUIRED.

That's what I'm expecting from generator:

    [TestFixture]
    public class PropertiesShouldNotBeRequiredTest
    {
        public class IssueModel
        {
            public int IssueId { get; set; }//default is 0 and it is ok
            public string Title { get; set; }
            public string Description { get; set; }
            public object OptionalProperty { get; set; }
            public int? NotUsedInt { get; set; }
        }

        [Test]
        public void Test()
        {
            var schemaGenerator = new JSchemaGenerator();
            var jsonSchema = schemaGenerator.Generate(typeof(IssueModel));

            Assert.AreEqual(0, jsonSchema.Required.Count);
        }
    }

Unable to cast object of type 'Newtonsoft.Json.Converters.XmlDocumentWrapper' to type 'Newtonsoft.Json.Converters.IXmlElement'.

I am trying to convert a JSON instance to an XML document in my code, using this syntax:
outputXmlInstance = Newtonsoft.Json.JsonConvert.DeserializeXmlNode(inputJsonInstance)

Sometimes it throws the error mentioned in the subject line. This JSON instance throws an error:

{
    "Id": 1,
     "Email": "[email protected]",
     "Active": true,
     "CreatedDate": "2013-01-20T00:00:00Z",
     "Roles": [
       "User",
       "Admin"
     ],
    "Team": {
        "Id": 2,
        "Name": "Software Developers",
        "Description": "Creators of fine software products and services."
    }
}

While this does not throw an error:

{
    "verificationServices": {
        "region": "XXXX",
        "parentCompany": "XXX",
        "parentCompanyStatus": "Active",
        "parentLegalName": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "parentCompanyAddress": {
            "addressLine1": "XXXXXXXXXXXXXXXXXXXXXXXX",
            "city": "XXXXXXXXXXXXXXXXXXXXXXXX",
            "state": "XX",
            "zip": "XXXXXXXXXX"
        }
    }
}

Both JSON instances are valid, and nothing jumps out to me as the cause. Could you please help us?
Thanks.

PlatformNotSupportedException on Ubuntu

I get the following exception when I want to register a license on Ubuntu:

Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.PlatformNotSupportedException: Operation is not supported on this platform.
at Newtonsoft.Json.Schema.Infrastructure.Licensing.CryptographyHelpers.ValidateData(Byte[] data, Byte[] signature)
at Newtonsoft.Json.Schema.Infrastructure.Licensing.LicenseHelpers.RegisterLicense(String license, DateTime releaseDate)
at Newtonsoft.Json.Schema.Infrastructure.Licensing.LicenseHelpers.RegisterLicense(String license)
at Autodesk.Forge.Dm.Server.Startup.ConfigureServices(IServiceCollection services)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)

Resolving referenced schema on local filesystem fails if the BaseUri contains whitespaces

I'm trying to resolve a referenced schema on my local filesystem like described in the documentation:

string schemapath = @"C:\Users\myusername\Desktop\Test\contacts.schema.json";

using (StreamReader file = File.OpenText(schemapath))
using (JsonTextReader reader = new JsonTextReader(file))
{
    JSchemaUrlResolver resolver = new JSchemaUrlResolver();

    JSchema schema = JSchema.Load(reader, new JSchemaReaderSettings
    {
        Resolver = resolver,                   
        BaseUri = new Uri(schemapath)
     });
}

This works fine as long as the schemapath does not contain any whitespaces. Placing the schemas in a folder containing whitespaces like so string schemapath = @"C:\Users\myusername\Desktop\Test with whitespace\contacts.schema.json"; leads to the following exception:

Newtonsoft.Json.Schema.JSchemaReaderException was unhandled by user code
  HResult=-2146233088
  LineNumber=4
  LinePosition=12
  Message=Error when resolving schema reference 'contact.schema.json'. Path 'items', line 4, position 12.
  Path=items
  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)
       at JsonNetSchemaTest.SchemaGeneratorTest.TestCreateWithWhitespace() in ...
  InnerException: 
       HResult=-2147024893
       Message=Could not find a part of the path 'C:\Users\myusername\Desktop\Test%20with%20whitespace\contact.schema.json'.
       Source=mscorlib
       StackTrace:
            at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
            at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
            at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
            at Newtonsoft.Json.Schema.Infrastructure.WebRequestDownloader.GetStream(Uri uri, ICredentials credentials, Nullable`1 timeout, Nullable`1 byteLimit)
            at Newtonsoft.Json.Schema.JSchemaUrlResolver.GetSchemaResource(ResolveSchemaContext context, SchemaReference reference)
            at Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ResolvedSchema(Uri schemaId, Uri resolvedSchemaId)
            at Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.ResolveDeferedSchema(DeferedSchema deferedSchema)
       InnerException: 

The schemas I used are pretty basic:

contacts.schema.json

{
  "title": "Contact list",
  "type": "array",
  "items": {
    "$ref": "contact.schema.json"
  }
}

contact.schema.json

{
  "title": "Contact information",
  "type": "object",
  "properties": {
    "FirstName": {
      "title": "First name",
      "type": "string"
    },
    "FamilyName": {
      "title": "Family name",
      "type": "string"
    }
  },
  "required": [
    "FirstName",
    "FamilyName"
  ]
}

Schema generator doesn't create correct links to types.

When generating schema on complex object graphs. Schema generator only creates valid schema when SchemaIdGenerationHandling set to None. Otherwise the links to types are missing #/definition prefix and you cannot even load schema back. It fails a validity check.
Using Json 9.0.1 and latest 2.3 schema

void Main()
{
                var generator = new JSchemaGenerator
                {
                    SchemaReferenceHandling = SchemaReferenceHandling.Objects,
                    SchemaIdGenerationHandling = SchemaIdGenerationHandling.AssemblyQualifiedName,
                    GenerationProviders = { new StringEnumGenerationProvider() },
                    SchemaLocationHandling = SchemaLocationHandling.Definitions
                };
    var schema = generator.Generate(typeof(TestComplexClass));
    var sSchema = schema.ToString();
    var newSchema = JSchema.Load(new JsonTextReader(new StringReader(sSchema)));
}

public class TestComplexClass
{
    public int Counter { get; set; }
    public TestClass TestProperty { get; set; }
}

public class TestClass
{ 
    public int MyProperty { get; set; }
    public string MyStringProperty { get; set; }
}

Schema Hierarchy Request

Hi

I am currently using Json.Schema more as a definition that a validation. I wrote a little wrapper around it to get things like parent and get a certain child with a path (jsonPath ish) and name of current without extentiondata but based on parent and so on.

Would it be possible to add some sort of Hierarchy like Jobject. So that you can go parent. Like i said not really using it as "here is json is it valid".

thanks

Unable to validate Invalid Email ID (some invalid patterns) with "format:email"

Hi,

I'm trying to validate some email address, but its not validating some invalid patterns.

Here is my Schema and the JSON

{
"description" : "Example Contact Information Array JSON Schema",
"type" : "array",
"items" : {
"title" : "A Contact Information object",
"type" : "object",
"properties" : {
"name" : {
"type" : "string",
"enum" : ["home", "work", "other"]
},
"email" : {
"type" : "string",
"optional" : true,
"format" : "email"
}
},
"minItems" : 1,
"maxItems" : 5
}
}

JSON:

[{
"name": "home",
"email": "[email protected]"
},
{
"name": "work",
"email": "{[email protected]"
}]

The email provided above "{[email protected]" is invalid, but when I tried with http://www.jsonschemavalidator.net/ its not showing any errors. At the same time if I write like "email": "{[email protected]}" added another closing brace then it is able to validate saying invalid email.

Please check this.

Validation Errors, Required for Circular References

Given the following POCO's:

class User : Model
{
    [Key]
    [Required]
    public int Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Address HomeAddress { get; set; }
    public Address WorkAddress { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime CreatedAt { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime ModifiedAt { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime? DeletedAt { get; set; }
}
class Address : Model
{
    [Key]
    [Required]
    public int Id { get; set; }

    public User HomeUser { get; set; }
    public User WorkUser { get; set; }

    public int StreetNo { get; set; }
    public string StreetName { get; set; }
    public string City { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime CreatedAt { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime ModifiedAt { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime? DeletedAt { get; set; }
}

Generating a schema for a User using the following code:

var generator = new JSchemaGenerator();
var schemaJson = generator.Generate(typeof(User)).ToString();

Produces the following output:

{
  "type": "object",
  "properties": {
    "Id": {
      "type": "integer"
    },
    "FirstName": {
      "type": [
        "string",
        "null"
      ]
    },
    "LastName": {
      "type": [
        "string",
        "null"
      ]
    },
    "HomeAddress": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "Id": {
          "type": "integer"
        },
        "HomeUser": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "Id": {
              "type": "integer"
            },
            "FirstName": {
              "type": [
                "string",
                "null"
              ]
            },
            "LastName": {
              "type": [
                "string",
                "null"
              ]
            },
            "HomeAddress": {
              "$ref": "#/properties/HomeAddress"
            },
            "WorkAddress": {
              "$ref": "#/properties/HomeAddress"
            },
            "CreatedAt": {
              "type": "string",
              "format": "date-time"
            },
            "ModifiedAt": {
              "type": "string",
              "format": "date-time"
            },
            "DeletedAt": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            }
          },
          "required": [
            "Id",
            "FirstName",
            "LastName",
            "HomeAddress",
            "WorkAddress",
            "CreatedAt",
            "ModifiedAt",
            "DeletedAt"
          ]
        },
        "WorkUser": {
          "$ref": "#/properties/HomeAddress/properties/HomeUser"
        },
        "StreetNo": {
          "type": "integer"
        },
        "StreetName": {
          "type": [
            "string",
            "null"
          ]
        },
        "City": {
          "type": [
            "string",
            "null"
          ]
        },
        "CreatedAt": {
          "type": "string",
          "format": "date-time"
        },
        "ModifiedAt": {
          "type": "string",
          "format": "date-time"
        },
        "DeletedAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        }
      },
      "required": [
        "Id",
        "HomeUser",
        "WorkUser",
        "StreetNo",
        "StreetName",
        "City",
        "CreatedAt",
        "ModifiedAt",
        "DeletedAt"
      ]
    },
    "WorkAddress": {
      "$ref": "#/properties/HomeAddress"
    },
    "CreatedAt": {
      "type": "string",
      "format": "date-time"
    },
    "ModifiedAt": {
      "type": "string",
      "format": "date-time"
    },
    "DeletedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  },
  "required": [
    "Id",
    "FirstName",
    "LastName",
    "HomeAddress",
    "WorkAddress",
    "CreatedAt",
    "ModifiedAt",
    "DeletedAt"
  ]
}

Given the following input json:

{
  "$id": "1",
  "Id": 1,
  "FirstName": "Brad",
  "LastName": "Jones",
  "HomeAddress": {
    "$id": "2",
    "Id": 1,
    "HomeUser": {
      "$ref": "1"
    },
    "WorkUser": null,
    "StreetNo": 20,
    "StreetName": "Foo Street",
    "City": "Bar Land",
    "CreatedAt": "2015-08-25T05:56:31.0580281",
    "ModifiedAt": "2015-08-25T05:56:31.0580281",
    "DeletedAt": null
  },
  "WorkAddress": {
    "$id": "3",
    "Id": 2,
    "HomeUser": null,
    "WorkUser": {
      "$ref": "1"
    },
    "StreetNo": 190,
    "StreetName": "Queen Street",
    "City": "Melbourne",
    "CreatedAt": "2015-08-25T05:56:31.1049033",
    "ModifiedAt": "2015-08-25T05:56:31.1049033",
    "DeletedAt": null
  },
  "CreatedAt": "2015-08-25T05:56:31.0424028",
  "ModifiedAt": "2015-08-25T05:56:31.0580281",
  "DeletedAt": null
}

I get the following error (repeated twice):

  • Message: Required properties are missing from object: Id, FirstName, LastName, HomeAddress, WorkAddress, CreatedAt, ModifiedAt, DeletedAt.
  • Schema path: #/properties/HomeAddress/properties/HomeUser/required

Feel free to put the schema and input json into: http://www.jsonschemavalidator.net/ The exact same errors are reported.

If I manually remove the "required" array #/properties/HomeAddress/properties/HomeUser/required then validation passes.

I am undecided if removing the array is the correct thing to do, regardless I have tried creating a custom SchemaProvider to automatically remove the array:

class FixNestedRequiredSchemaProvider : JSchemaGenerationProvider
{
    private static List<Type> VisitedTypes = new List<Type>();

    public override JSchema GetSchema(JSchemaTypeGenerationContext context)
    {
        if (context.ObjectType.IsSubclassOf(typeof(Model)))
        {
            JSchemaGenerator generator = new JSchemaGenerator();
            generator.GenerationProviders.Add(new FixNestedRequiredSchemaProvider());
            JSchema schema = generator.Generate(context.ObjectType, context.Required != Required.Always);
            schema.Format = "object";

            if (VisitedTypes.Contains(context.ObjectType))
            {
                schema.Required.Clear();
            }

            VisitedTypes.Add(context.ObjectType);

            return schema;
        }

        // use default schema generation for all other types
        return null;
    }
}

That failed with the following exception:

Newtonsoft.Json.Schema.JSchemaException : The free-quota limit of 10 schema generations per hour has been reached. Please visit http://www.newtonsoft.com/jsonschema to upgrade to a commercial license.

I feel like even if I buy the licence it's just going to recurse forever and I'll end up with a StackOverFlow exception.

Does ReferenceLoopHandling.Ignore have any effect in Json.Schema???

Cheers Brad

Not able to see Model Validation

After using this library I was not able to see the model validation message which was define in Class Property.

[DataContract]
public class Request
{
[DataMember]
[Required(ErrorMessage = Constants.ModelError.VersionRequired, AllowEmptyStrings = true)]
[RegularExpression(Constants.RegularExpressionVersion, ErrorMessage = Constants.ModelError.VersionInvalid)]
[MinLength(1, ErrorMessage = Constants.ModelError.VersionInvalid)]

    public string Version { get; set; }

}

Not able to see this error message.

Malformed $ref generation

Hello !
I am using Json.NET Schema 2.0.4 with Json.Net 9.0.1.
I have created these following classes .

    public class A
    {
        public string Value { get; set; }
    }

    public class B
    {
        public string ValueB { get; set; }
    }

    public class Item
    {
        public A ItemA { get; set; }
        public B ItemB { get; set; }

        public List<A> ItemAs { get; set; }
        public List<B> ItemBs { get; set; }  
    }

    public class BigItem
    {
        public Item SmallItem { get; set; }
    }

Expected Json Schema . When a property has a type of {Classname} , {Classname} should be put in definitions.

{
  "definitions" : {
    "A" : {
     "type" : "object",
      "properties" : {
        "Value" : {
          "type" : "string"
        }
      }
    },
    "B" : {
      "type" : "object",
      "properties" : {
        "ValueB" : {
          "type" : "string"
        }
      }
    },
    "Item" : {
      "type" : "object",
      "properties" : {
        "ItemA" : {
          "$ref" : "#/definitions/A"
        },
        "ItemB" : {
          "$ref" : "#/definitions/B"
        },
        "ItemAs" : {
          "type" : "array",
          "items" : {
            "$ref" : "#/definitions/A"
          }
        }
      }
    }
  },
  "type" : "object",
  "properties" : {
    "SmallItem" : {
      "$ref" : "#/definitions/Item"
    }
  }
}

Generated Json Schema . Which has a malformed $ref which cannot be validated .

{
  "definitions": {
    "Item": {
      "type": "object",
      "properties": {
        "ItemA": {
          "type": "object",
          "properties": {
            "Value": {
              "type": "string"
            }
          }
        },
        "ItemB": {
          "type": "object",
          "properties": {
            "ValueB": {
              "type": "string"
            }
          }
        },
        "ItemAs": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Item/properties/ItemA"
          }
        },
        "ItemBs": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Item/properties/ItemB"
          }
        }
      }
    },
    "A": {
      "$ref": "#/definitions/Item/properties/ItemA"
    },
    "B": {
      "$ref": "#/definitions/Item/properties/ItemB"
    }
  },
  "type": "object",
  "properties": {
    "SmallItem": {
      "$ref": "#/definitions/Item"
    }
  }
}

Edit :
Temporarily this can be fixed with using SchemaReferenceHandling

generator.SchemaReferenceHandling = SchemaReferenceHandling.None;

Type null values

Hi

When i have a schema where the type field is not provided it return null(not JSchemaType.Null) When i have type : null or type:"" it throws an exception. Should it not be set to JSchemaType.Null or JSchemaType.None for all the above cases.

Had a look at schema definition and there is a null but there is no real rules around it.

thanks

StackOverflowException in FindSchema

Hello,
The following schema causes a StackOverflowException on JSchema.Parse():

{
  "type" : "object",
  "properties" : {
      "test" : {"$ref" : "#/definitions/b" }
  },

  "definitions": {

    "a" : {
      "type":"string"
    },
    "b": {
      "type": "object",
      "properties": {
        "b2" : { "$ref": "#definitions/a" }
      }
    }
  }
}

Note that one of the schema in the definitions section references another schema in definitions. The unterminated recursion appears to be in FindSchema().
The schema parses correctly in, for example, https://json-schema-validator.herokuapp.com/

Nullable Property of Enum type breaks validation

Generated schema on type containing nullable enum type Property. All validation attempts on objects with the property actually set to null fail. I am using 9.0.1 json and latest 2.3 schema. Below is the code (made in LinqPad) sorry tried to use .netfiddle, but it doesn't work with v9 Json. The schema itself looks legit. So I guess the issue is in validation?

Also worth noting that setting DefaultRequired makes no difference on schema content.

void Main()
{
    var generator = new JSchemaGenerator() { DefaultRequired = Required.AllowNull};
      var schema = generator.Generate(typeof(TestClass));
      //schema.ToString().Dump();

      var testObject = new TestClass();
      var jObject = JObject.FromObject(testObject);
      jObject.Validate(schema);
}

public class TestClass
{
    public int Counter { get; set; }
    public TestEnum? TestProperty { get; set; }
}

public enum TestEnum
{ 
    none,one,two
}

//{
//  "type": "object",
//  "properties": {
//      "Counter": {
//          "type": "integer"
//      },
//    "TestProperty": {
//          "type": [
//            "integer",
//            "null"
//      ],
//      "enum": [
//        0,
//        1,
//        2
//      ]
//    }
//  },
//  "required": [
//    "Counter",
//    "TestProperty"
//  ]
//}

Regular expressions validation and JSON Schema specification

The JSON Schema specification requires (edited) recommends the regular expressions to be ECMA 262 compliant. The grammar for ECMA 262 specification.
The problem is that current implementation validates successfully schemas with the following regexp: "pattern" : "^\\S(|(.|\\n)*\\S)\\Z", which is not ECMA 262 compliant ('\Z' is not special literal).
The problem is reproducible in the online version.
Example schema:

{
   "$schema" : "http://json-schema.org/draft-04/schema#",
   "title" : "listing/delete",
   "type" : "object",
   "additionalProperties" : false,
   "id" : "http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/delete.json",
   "properties" : {
      "listing_reference" : {
         "type" : "string",
         "pattern" : "^\\S(|(.|\\n)*\\S)\\Z"
      },
      "deletion_reason" : {
         "enum" : [
            "withdrawn",
            "offer_accepted",
            "exchanged",
            "completed",
            "let"
         ]
      }
   },
   "required" : [
      "listing_reference"
   ]
}

Example request:

{
 "listing_reference":"d"
}

No validation extensiblity?

I could find no extensibility point for schema validation. I was looking specifically for custom format validation, which is mentioned in the specs. I may also want to do custom validation at specific points, but there's no way to hook into the validation step either.

Have I missed something?

The open source golang implementation has support for custom format validation, for example:

gojsonschema

For repetitive or more complex formats, you can create custom format checkers

Also: Would you take pull requests for this?

StackOverflowException in JSchemaReader.LoadAndSetSchema()

I have two files that reference to each other. They stored in local directory and I use relative references for this purpose.

First: obj_branch.schema.json

{
"$schema": "http://json-schema.org/draft-03/schema#",
"id": "obj_branch.schema.json",
"type": "object",
"additionalProperties": false,
"properties": {
"see_also": {
"extends": { "$ref" : "prop_see_also.schema.json" }
}
}
}

Second: prop_see_also.schema.json

{
"$schema": "http://json-schema.org/draft-03/schema#",
"id": "prop_see_also.schema.json",
"type": "array",
"items": {
"extends": { "$ref" : "obj_branch.schema.json" }
}
}

StackOverflowException was thrown when I tried to parse first schema (obj_branch.schema.json) like this:

        const string DIRECTORY = @"E:\SchemaDir\";

        var schemaJson = File.ReadAllText(Path.Combine(DIRECTORY, "obj_branch.schema.json"));
        var schema = JSchema.Parse(schemaJson, new JSchemaReaderSettings
        {
            BaseUri = new Uri(DIRECTORY),
            Resolver = new JSchemaUrlResolver()
        });

Json Schema Validation - uppercase hostname in ID property causes validation error.

Hi,

We identified an issue with schema resolution/validation.

The issue can be recreated by using the below schema at http://www.jsonschemavalidator.net/.

Changing the ID value on the 2nd line to be lowercase resolves the issue.

We don't think this would be expected behaviour?

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://DTCP05IFCENT01.qa.local:8080/identity-management/v1/authenticated.json",    
"user-definitions": {
        "application-properties": {
            "type": "object",
            "properties": {}
        },
        "application-context": {
            "type": "object",
            "properties": {}
        },
        "application-payload": {
            "type": "object",
            "properties": {}
        }
    },
    "definitions": {
        "event": {
            "type": "object",
            "allOf": [
                {
                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/v1/instance.json"
                },
                {
                    "properties": {
                        "system": {
                            "$ref": "http://dtcp05ifcent01.QA.LOCAL:8080/event-management/v1/system.json"
                        },
                        "application": {
                            "$ref": "#/definitions/application"
                        }
                    },
                    "required": [
                        "system",
                        "application"
                    ]
                },
                {
                    "properties": {
                        "system": {
                            "allOf": [
                                {
                                    "properties": {
                                        "security": {
                                            "allOf": [
                                                {
                                                    "properties": {
                                                        "user": {
                                                            "oneOf": [
                                                                {
                                                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/users/v1/activedirectory.json"
                                                                },
                                                                {
                                                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/users/v1/system.json"
                                                                },
                                                                {
                                                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/users/v1/portal.json"
                                                                }
                                                            ], 
                                                            "properties": {
                                                                "isSo" : {
                                                                    "type": "boolean"
                                                                },
                                                                "username" : {
                                                                    "type": "string"
                                                                },
                                                                "userRole" : {
                                                                    "type": "string"
                                                                },
                                                                "lastLogin" : {
                                                                    "type": "string"
                                                                }
                                                            },
                                                            "required": ["isSo", "username", "userRole", "lastLogin"]
                                                        }
                                                    }
                                                },
                                                {
                                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/event-management/v1/system-security.json"
                                                }
                                            ]
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        },
        "application": {
            "type": "object",
            "allOf": [
                {
                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/v1/instance.json"
                },
                {
                    "properties": {
                        "properties": {
                            "type": "object",
                            "allOf": [
                                {
                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/v1/instance.json"
                                },
                                {
                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/event-management/v1/application-properties.json"
                                },
                                {
                                    "$ref": "#/user-definitions/application-properties"
                                }
                            ]
                        },
                        "context": {
                            "type": "object",
                            "allOf": [
                                {
                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/v1/instance.json"
                                },
                                {
                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/event-management/v1/application-context.json"
                                },
                                {
                                    "$ref": "#/user-definitions/application-context"
                                }
                            ]
                        },
                        "payload": {
                            "type": "object",
                            "allOf": [
                                {
                                    "$ref": "http://dtcp05ifcent01.qa.local:8080/common/v1/instance.json"
                                },
                                {
                                    "$ref": "#/user-definitions/application-payload"
                                }
                            ]
                        }
                    },
                    "required": [
                        "properties",
                        "payload"
                    ]
                }
            ]
        }
    },
    "type": "object",
    "properties": {
        "event": {
            "$ref": "#/definitions/event"
        }
    },
    "required": [
        "event"
    ]
}

relative paths and definitions

to support relative reference paths like { "$ref": "foo.schema.json" } i had to write a custom JSchemaResolver. by that the parser lost the ability to resolve references to internal definitions like { "$ref": "#/definitions/bar" } : they are routed through my custom resolver, too.

so do i have to write a custom implementation to support absolute, relative and internal references or is there another way?

i think all that should be handled by the framework. or at least the user should be able to compose a resolver without losing features.

Bug in JsonSchemaBuild.ProcessSchemaProperties

The handling for the "required" tagname accommodates only the use of the "required" keyword on a specific property. It assumes the associated value is a Boolean.

case JsonSchemaConstants.RequiredPropertyName:
CurrentSchema.Required = (bool)property.Value;
break;

When a required properties array is encountered, it throws an exception.
e.g.:
this works:
"properties":{"Key":{"type":"string","required":true},"Value":{"type":"string"}}

and this triggers an ArgumentException("Can not convert {0} to Boolean.") from JToken:
"properties":{"Key":{"type":"string"},"Value":{"type":"string"}},
"required":["Key"]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.