NjsonSchema验证如果Property1等于Something,则需要Property2



我似乎无法让const或enum作为if-then-else JSON模式验证的一部分工作。

当涉及到1个验证值时,它们似乎是可互换的。(参考(

这是我的JSON模式

{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Test_Schema",
"description": "A schema for validating a test object",
"type": "object",
"additionalProperties": false,
"properties": {
"GeneralData": {
"type": "object",
"description": "Advsor and admin customer information",
"properties": {
"Name": {
"type": [ "string", "null" ],
"description": "Customer's advisor name"
},
"Age": {
"type": [ "string", "null" ],
"description": "Customer's advisor email"
},
"Location": {
"type": [ "string", "null" ],
"description": "The advisor's manager email'"
}
},
"required": [ "Name", "Location", "Age" ]
},
"ClientData": {
"type": "object",
"description": "Customer's information",
"additionalProperties": false,
"properties": {
"Title": {
"type": [ "string", "null" ]
},
"Forename": {
"type": [ "string", "null" ]
},
"Surname": {
"type": [ "string" ]
}
},
"required": [ "Title" ],
"if": {
"properties": {
"Forename": { "enum": [ "Soameonea" ] }
},
"required": [ "Forename" ]
},
"then": { "required": [ "Surname" ] },
"else": false 
}
}
}

如果Forename=";某人"我想要求填写姓氏。

这是我序列化后的jsonObject:

{
"GeneralData": {
"Name": "Not Relevant",
"Age": "Not Relevant",
"Location": "Not Relevant"
},
"ClientData": {
"Title": "SomeTitle",
"Forename": "Someone",
"Surname": null
}
}

验证码:

internal void ValidateDataObjectOnSchema()
{
var dataObject = PopulateDataObject();
var json = JsonConvert.SerializeObject(dataObject);
var result = GetSchema().Validate(json);
var errors = result.Select(x =>
{
return new Errors() { Title = x.Property, Description = x.Schema.Description };
});
var i = errors;

}
internal JsonSchema GetSchema()
{
return JsonSchema.FromFileAsync("Test/testSchema.json").Result;
}

现在它仍然需要姓氏,即使枚举Soameonea!=我和某人只需要头衔<==问题1

在JSON模式中,如果我设置";姓氏":{"type":["string","null]},然后错误消失,如果我将Forename枚举的if条件更改为";某人"lt;==第2期

如果我用Const替换Enum,我就无法获得不同的验证输出,所以如果我能让一个生效,我相信另一个也会生效。

我已经找到了这个问题的几个答案(答案1(,我试图实现同样的东西,但由于某种原因,它在我的情况下失败了。

我错过了什么?

在JSON模式中,如果我设置;姓氏":{"type":["string","null]},则错误消失

具有null值的属性仍然具有值。如果您想说属性值不仅必须存在,而且不能为null,那么将"type": "string"添加到then条件中。

更新:正如@Relequstial在其中一条评论中提到的那样,NJson Schema似乎只支持草案04,这就是为什么if-then-else不起作用,应该使用隐含。以下是我的替代方案

Newtonsoft.json.Schema(参考(包使用相同的代码和json

代码:

internal void ValidateDataObjectOnSchemaWithNewtonSoftJson()
{
var dataObject = PopulateDataObject();
var settings = new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
};
var jsonDataObjectString = JsonConvert.SerializeObject(dataObject, settings);
JObject jsonDataObject = JObject.Parse(jsonDataObjectString);
var jsonSchemaFile = File.ReadAllText("Test/testSchema.json");
var schema = JSchema.Parse(jsonSchemaFile);
;
IList<ValidationError> messages;
var result = jsonDataObject.IsValid(schema, out messages);
var errors = GetReadableResult(result, messages);
}
private List<Errors> GetReadableResult(bool result, IList<ValidationError> messages)
{
var errors = new List<Errors>();
if (!result)
{
foreach (var error in messages)
{
if (error.ChildErrors.Count > 0)
{
errors.Add(
new Errors()
{
Path = error.ChildErrors.FirstOrDefault()?.Path,
Kind = error.ChildErrors.FirstOrDefault()?.Message
});
}
else
{
errors.Add(new Errors()
{
Path = error.Path,
Kind = error.Message
});
}
}
}
return errors;
}

JsonSchema:

{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Test_Schema",
"description": "A schema for validating a test object",
"type": "object",
"additionalProperties": false,
"properties": {
"GeneralData": {
"type": "object",
"description": "Advsor and admin customer information",
"properties": {
"Name": {
"type": [ "string", "null" ],
"description": "Customer's advisor name"
},
"Age": {
"type": [ "string", "null" ],
"description": "Customer's advisor email"
},
"Location": {
"type": [ "string", "null" ],
"description": "The advisor's manager email'"
}
},
"required": [ "Name", "Location", "Age" ]
},
"ClientData": {
"type": "object",
"description": "Customer's information",
"additionalProperties": false,
"properties": {
"Title": {
"type": [ "string", "null" ]
},
"Forename": {
"type": "string"
},
"Surname": {
"type": [ "string" ]
}
},
"required": [ "Title" ],
"if": {
"properties": {
"Forename": { "enum": [ "Someone" ] }
},
"required": [ "Forename" ]
},
"then": { "required": [ "Surname" ] },
"else": {}
}
}
}

唯一的添加是使具有多个子项的Errors的GetReadableResult递归。

最新更新