James MA James MA - 3 months ago 30
C# Question

How can I set the AllowAdditionalProperties to ture in generating the schema with NJsonSchema

We are now going to use NJsonSchema to check the Json files for required fields only, and we allow user to add some extra fields for their local use. So, it has to allow additional properties in the Json file.

By using the NJsonSchma, there has the setting for additionalProperties, but when we gernate the schema using FromType, and then set the option AllowAdditionalProperties, it will apply to the top level only,

For example:

NJsonSchema.JsonSchema4 schema = JsonSchema4.FromType<Top>();
schema.AllowAdditionalProperties = true;

public class Item
{
public string code { get; set; }
public string name { get; set; }
}

public class Top
{
public List<Item> data { get; set; }
}


Now, it allows additional properties for Top, but not for Item.
i.e.

// allowed even ref is not defined in Top
var js = "{\"data\":[{\"code\":\"A01\",\"name\":\"apple\"}],\"ref\":\"A01\"}";

// ArrayItemNotValid as price is not defined in Item
var js = "{\"data\":[{\"code\":\"A01\",\"name\":\"apple\",\"price\":1.0}],\"ref\":\"A01\"}";


We even try to build a iteration function to set the value in properties dictionary, but it still cannot change the behavior:

public static void SetAditionalProperties(JsonProperty jp)
{
jp.AllowAdditionalProperties = true;
foreach (KeyValuePair<string, JsonProperty> kv in jp.Properties)
{
SetAditionalProperties(kv.Value);
}
}


The only thing we can do now is to download the source, and change the getter of AllowAdditionalProperties to return true all the time. Of course we know that this is not a proper way, but we can't find any alternative at this moment, and we'd like to use a proper way later if any.

It seems that this is just a default setting in generating the schema, but we can't find such option (maybe we have missed), does anyone know how we can change this setting in generating the schema?

Answer

You have to implement your own JsonSchemaGenerator:

public class MyJsonSchemaGenerator : JsonSchemaGenerator
{
    public MyJsonSchemaGenerator(JsonSchemaGeneratorSettings settings)
        : base(settings)
    {
    }

    protected override void GenerateObject<TSchemaType>(Type type, TSchemaType schema, ISchemaResolver schemaResolver, ISchemaDefinitionAppender schemaDefinitionAppender)
        where TSchemaType : JsonSchema4, new()
    {
        base.GenerateObject(type, schema, rootSchema, schemaDefinitionAppender, schemaResolver);
        schema.AllowAdditionalProperties = true;
    }
}

Then you can generate the schema like this:

var generator = new MyJsonSchemaGenerator(new JsonSchemaGeneratorSettings());
var schema = generator.Generate(typeof (Person), new SchemaResolver());
Comments