我就像尝试使用Joi.alternatives.try()创建Joi模式一样。这是我尝试过的模式。
Joi.alternatives().try(Joi.object({
type: Joi.number().required().label('Error1!!')
}), Joi.object({
reason: Joi.string().required().label('Error2!!')
})).label('Error!!')
这是我使用过的对象。
{ reason: 2 }
我期望错误为Error2!!
或包含字符串Error2!!
的错误。但是我收到错误消息
Validation Error: "Error!!" does not match any of the allowed types
此错误来自父节点。
如何使错误特定于对象?也就是说,错误来自替代对象节点而不是父对象。
您可以使用this平台在线验证架构。
更新: 这是我使用的示例架构。
employee_retired = Joi.object({
type: Joi.number().required().valid(2, 3, 7),
reason: Joi.string().required()
.min(1)
.max(100),
firstname: Joi.string()
.required(),
lastname: Joi.string()
.required()
.min(1)
.max(255),
personaldetails: Joi.alternatives().conditional('type', {
is: 2, then: Joi.array().items(Joi.object({
address: Joi.string().required()
.min(1)
.max(100),
salary: Joi.string().required()
.min(0)
.max(500),
contactnumbers: Joi.array().items(Joi.object({
mobile: Joi.string().required()
.min(0)
.max(15),
home: Joi.string()
.required()
.min(1)
.max(15),
})).max(50).required(),
}).required()).max(50).required(),
otherwise: Joi.forbidden(),
}),
monthlysavings: Joi.alternatives().conditional('type', {
is: 3,
then: Joi.number()
.required()
.min(0)
.max(50000),
otherwise: Joi.forbidden(),
}),
isapproved: Joi.boolean().required(),
});
empolyee_working = Joi.object({
type: Joi.number().required().valid(2, 3, 7),
reason: Joi.string().required()
.min(1)
.max(100),
firstname: Joi.string()
.required(),
lastname: Joi.string()
.required()
.min(1)
.max(255),
contactnumbers: Joi.array().items(Joi.object({
mobile: Joi.string().required()
.min(0)
.max(15),
home: Joi.string()
.required()
.min(1)
.max(15),
})).max(50).required(),
monthlysavings: Joi.alternatives().conditional('type', {
is: 3,
then: Joi.number().required()
.min(1)
.max(50000),
otherwise: Joi.forbidden(),
}),
isapproved: Joi.boolean().required(),
})
const employee = Joi.alternatives().try(employee_retired, empolyee_working);
答案 0 :(得分:2)
您可以使用object.or
来解决此问题:
Joi.object({
type: Joi.number().label('Error1!!'),
reason: Joi.string().label('Error2!!')
}).or('type', 'reason').label('Error!!')
测试:
{}
// Validation Error: "Error!!" must contain at least one of [Error1!!, Error2!!]
{ reason: 2 }
// Validation Error: "Error2!!" must be a string
{ type: "a" } // note that due to default `convert` behavior, `{ type: "2" }` would pass
// Validation Error: "Error1!!" must be a number
{ a: "b" }
// Validation Error: "a" is not allowed. "Error!!" must contain at least one of [Error1!!, Error2!!]
确实有点冗长,但遵循相同的逻辑:
personaldetails
和contactnumbers
有所不同因此,以下几行内容应为您提供精确的验证错误消息(尽管我没有测试所有情况)。我只是“合并”了两个员工声明,两个不同的案例personaldetails
和contactnumbers
不再声明为required
,而是在最后的or
中指定。
Joi.object({
type: Joi.number().required().valid(2, 3, 7),
reason: Joi.string().required()
.min(1)
.max(100),
firstname: Joi.string()
.required(),
lastname: Joi.string()
.required()
.min(1)
.max(255),
personaldetails: Joi.alternatives().conditional('type', {
is: 2, then: Joi.array().items(Joi.object({
address: Joi.string().required()
.min(1)
.max(100),
salary: Joi.string().required()
.min(0)
.max(500),
contactnumbers: Joi.array().items(Joi.object({
mobile: Joi.string().required()
.min(0)
.max(15),
home: Joi.string()
.required()
.min(1)
.max(15),
})).max(50).required(),
// N.B.: no more .required() on the next line, .or() will handle it conditionally
}).required()).max(50),
otherwise: Joi.forbidden(),
}),
contactnumbers: Joi.array().items(Joi.object({
mobile: Joi.string().required()
.min(0)
.max(15),
home: Joi.string()
.required()
.min(1)
.max(15),
// N.B.: no more .required() on the next line, .or() will handle it conditionally
})).max(50),
monthlysavings: Joi.alternatives().conditional('type', {
is: 3,
then: Joi.number()
.required()
.min(0)
.max(50000),
otherwise: Joi.forbidden(),
}),
isapproved: Joi.boolean().required(),
}).or('personaldetails', 'contactnumbers').label('OR failure')