在使用 NJsonSchema 生成模式时如何将 AllowAdditionalProperties 设置为 true
How can I set the AllowAdditionalProperties to true in generating the schema with NJsonSchema
我们现在将使用 NJsonSchema 仅检查 Json 文件中的必填字段,并且我们允许用户添加一些额外的字段以供本地使用。因此,它必须允许 Json 文件中的其他属性。
通过使用 NJsonSchma,有 additionalProperties 的设置,但是当我们使用 FromType 生成模式,然后设置选项 AllowAdditionalProperties 时,它将仅应用于顶层,
例如:
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; }
}
现在,它允许 Top 的附加属性,但不允许 Item 的附加属性。
即
// 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\"}";
我们甚至尝试构建一个迭代函数来设置属性字典中的值,但它仍然无法改变行为:
public static void SetAditionalProperties(JsonProperty jp)
{
jp.AllowAdditionalProperties = true;
foreach (KeyValuePair<string, JsonProperty> kv in jp.Properties)
{
SetAditionalProperties(kv.Value);
}
}
我们现在唯一能做的就是下载源码,把AllowAdditionalProperties的getter一直改成returntrue。我们当然知道这不是一个合适的方法,但我们暂时找不到任何替代方法,如果有的话我们想在以后使用一个合适的方法。
这似乎只是生成模式的默认设置,但我们找不到这样的选项(也许我们错过了),有谁知道我们如何在生成模式时更改此设置?
在 SetAdditionalProperties
中,您还必须在 jp.Item
属性 上将 AllowAdditionalProperties
设置为真,如果它不为空...
您还应该在其他属性(即 Items、AdditionalPropertiesSchema 等)上进行设置
您必须实现自己的 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;
}
}
然后您可以像这样生成架构:
var generator = new MyJsonSchemaGenerator(new JsonSchemaGeneratorSettings());
var schema = generator.Generate(typeof (Person), new SchemaResolver());
我们现在将使用 NJsonSchema 仅检查 Json 文件中的必填字段,并且我们允许用户添加一些额外的字段以供本地使用。因此,它必须允许 Json 文件中的其他属性。
通过使用 NJsonSchma,有 additionalProperties 的设置,但是当我们使用 FromType 生成模式,然后设置选项 AllowAdditionalProperties 时,它将仅应用于顶层,
例如:
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; }
}
现在,它允许 Top 的附加属性,但不允许 Item 的附加属性。 即
// 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\"}";
我们甚至尝试构建一个迭代函数来设置属性字典中的值,但它仍然无法改变行为:
public static void SetAditionalProperties(JsonProperty jp)
{
jp.AllowAdditionalProperties = true;
foreach (KeyValuePair<string, JsonProperty> kv in jp.Properties)
{
SetAditionalProperties(kv.Value);
}
}
我们现在唯一能做的就是下载源码,把AllowAdditionalProperties的getter一直改成returntrue。我们当然知道这不是一个合适的方法,但我们暂时找不到任何替代方法,如果有的话我们想在以后使用一个合适的方法。
这似乎只是生成模式的默认设置,但我们找不到这样的选项(也许我们错过了),有谁知道我们如何在生成模式时更改此设置?
在 SetAdditionalProperties
中,您还必须在 jp.Item
属性 上将 AllowAdditionalProperties
设置为真,如果它不为空...
您还应该在其他属性(即 Items、AdditionalPropertiesSchema 等)上进行设置
您必须实现自己的 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;
}
}
然后您可以像这样生成架构:
var generator = new MyJsonSchemaGenerator(new JsonSchemaGeneratorSettings());
var schema = generator.Generate(typeof (Person), new SchemaResolver());