【问题标题】:How can I set the AllowAdditionalProperties to true in generating the schema with NJsonSchema如何在使用 NJsonSchema 生成架构时将 AllowAdditionalProperties 设置为 true
【发布时间】:2016-08-06 11:32:33
【问题描述】:

我们现在将使用NJsonSchema 来检查 Json 文件中的必填字段,并且我们允许用户添加一些额外的字段以供本地使用。因此,它必须允许 Json 文件中的其他属性。

通过使用NJsonSchma,有additionalProperties的设置,但是当我们使用FromType生成schema,然后设置选项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 更改为始终返回 true。我们当然知道这不是正确的方式,但目前我们找不到任何替代方法,如果有的话,我们希望以后使用正确的方式。

似乎这只是生成架构的默认设置,但我们找不到这样的选项(可能我们错过了),有谁知道我们如何在生成架构时更改此设置?

【问题讨论】:

    标签: c# json njsonschema


    【解决方案1】:

    你必须实现自己的 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());
    

    【讨论】:

    • 非常感谢,无需修改源代码即可使用。但是,只要查看JsonSchema4.cs中AllowAdditionalProperties的注释,似乎源内部有一些错误,因为预计该设置的默认值应该是true,但现在它是false。
    • 这不是错误:默认情况下 AllowAdditionalProperties 为 true(当您 new JsonSchema4() 时),但因为架构是从 C# 类生成的,所以此属性设置为 false(因为 C# 类通常不能有额外的属性——它们会在反序列化过程中丢失)。
    • 虽然 c# 类不能有其他属性,但经过验证的 json 可能
    【解决方案2】:

    SetAdditionalProperties 中,如果jp.Item 属性不为空,您还必须将AllowAdditionalProperties 设置为true...

    您还应该在其他属性(即 Items、AdditionalPropertiesSchema 等)上设置它

    【讨论】:

    • jp.Item 在 Properties 中,foreach 循环用于将所有 jp.Item 的 AllowAdditionalProperties 设置为 true,并且我们已经在调试模式下进行了检查。但是,当使用修改后的架构进行验证时,它不起作用。
    • BTW,不知道有没有其他方法可以直接更改设置?我不认为这种递归方法是正确的方法。如果我可以直接在单个命令中更改默认设置会更好(即与我将源更改为始终返回 true 的效果相同)。
    • 为了便于阅读,我建议将这三个答案合并到第一个答案中。后两个实际上只是 cmets/clarifications :)
    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多