NestJS - 基于一个属性有条件地验证主体

max*_*992 7 node.js typescript class-validator nestjs class-transformer

我正在尝试找到一种使用 DTO(使用辉煌class-validatorclass-transformer库)验证主体的好方法。它工作得非常好,即使对于嵌套结构也是如此,但在我的情况下,我希望根据某些条件拥有 body 属性。

可能有助于理解的示例:

让我们想象一下我的身体应该总是有selectedCategory。根据该字段,内容可能来自类别 1,其中包含prop1OR 来自类别 2,其中包含prop2.

我不想让他们两个都为空,我真的想要么已经prop1定义要么prop2基于selectedCategory.

我认为我可以使用管道,但是如何指定要使用的正确 DTO?

我已经构建了一个“基”类,其中包含所有公共属性和一些继承自它的其他类。

我可以根据属性手动实例化管道selectedCategory,这是理想的,但我不知道将什么作为管道的第二个参数(元数据)传递。

谢谢你的帮助。

Kim*_*ern 12

您是否尝试过使用?您只需创建一个 DTO,而不是拥有多个 DTO。每个属性都分配给一个或多个组:

@Min(12, {groups: ['registration', 'update']})
age: number;
@Length(2, 20, {groups: ['registration']})
name: string;
Run Code Online (Sandbox Code Playgroud)

然后,您可以有条件地将组传递给类转换器/验证器:

@Injectable()
export class ConditionalValidationPipe implements PipeTransform {
  async transform(entity: any, metadata: ArgumentMetadata) {
    // Dynamically determine the groups
    const groups = [];
    if (entity.selectedCategory === 1) {
      groups.push('registration');
    }

    // Transform to class with groups
    const entityClass = plainToClass(EntityDto, entity, { groups })

    // Validate with groups
    const errors = await validate(entityClass, { groups });
    if (errors.length > 0) {
      throw this.createError(errors);
    }
    return entityClass;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 您有关于如何在控制器中使用该管道的示例吗? (2认同)

Ale*_*one 9

您尝试过ValidateIf语句吗?

props1您可以对或进行多次验证props2,并相应地应用它们(如果selectedCategory是“类别 1”或“类别 2”)。