使用 Joi,要求两个字段之一为非空

Using Joi, require one of two fields to be non empty

如果我有两个字段,我只想在至少一个字段为非空字符串时进行验证,但在两个字段均为空字符串时失败。

类似这样的东西无法验证

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string()
}).or('a', 'b');

验证时

{a: 'aa', b: ''}

or 条件仅测试键 ab 是否存在,但会测试 ab 的条件是否存在是真的。 Joi.string() 对于空字符串将失败。

这里是要点和一些要演示的测试用例

http://requirebin.com/?gist=84c49d8b81025ce68cfb

下面的代码对我有用。我使用替代方案是因为 .or 确实在测试键的存在,而您真正想要的是一个替代方案,您可以让一个键或另一个为空。

var console = require("consoleit");
var Joi = require('joi');

var schema = Joi.alternatives().try(
  Joi.object().keys({
    a: Joi.string().allow(''),
    b: Joi.string()
    }),
  Joi.object().keys({
    a: Joi.string(),
    b: Joi.string().allow('')
    })
);

var tests = [
  // both empty - should fail
  {a: '', b: ''},
  // one not empty - should pass but is FAILING
  {a: 'aa', b: ''},
  // both not empty - should pass
  {a: 'aa', b: 'bb'},
  // one not empty, other key missing - should pass
  {a: 'aa'}
];

for(var i = 0; i < tests.length; i++) {
  console.log(i, Joi.validate(tests[i], schema)['error']);
}

如果你想表达 2 个字段之间的依赖关系而不必重复对象的所有其他部分,你可以使用 when:

var schema = Joi.object().keys({
  a: Joi.string().allow(''),
  b: Joi.string().allow('').when('a', { is: '', then: Joi.string() })
}).or('a', 'b');

另一种使用 Joi.when() 的方法对我有用:

var schema = Joi.object().keys({
  a: Joi.string().allow(''),
  b: Joi.when('a', { is: '', then: Joi.string(), otherwise: Joi.string().allow('') })
}).or('a', 'b')

.or('a', 'b') 防止 ab 为空(与 '' 相反)。

我遇到的问题 答案是,如果给定了两个字段,您将不会遇到任何错误,如果您想解决这个问题,您需要将 or 替换为 xor.