typescript 使用类验证器和 nestjs 验证嵌套对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53786383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:44:26  来源:igfitidea点击:

Validate nested objects using class validator and nestjs

javascriptnode.jstypescriptnestjsclass-validator

提问by Leonardo Emilio Dominguez

I'm trying to validate nested objects using class-validator and NestJS. I've already tried following this threadby using the @Typedecorator from class-transform and didn't have any luck. This what I have:

我正在尝试使用类验证器和 NestJS 验证嵌套对象。我已经尝试过使用class-transform 中的装饰器来关注此线程@Type,但没有任何运气。这是我所拥有的:

DTO:

DTO:

class PositionDto {
  @IsNumber()
  cost: number;

  @IsNumber()
  quantity: number;
}

export class FreeAgentsCreateEventDto {

  @IsNumber()
  eventId: number;

  @IsEnum(FinderGamesSkillLevel)
  skillLevel: FinderGamesSkillLevel;

  @ValidateNested({ each: true })
  @Type(() => PositionDto)
  positions: PositionDto[];

}

I'm also using built-in nestjs validation pipe, this is my bootstrap:

我也在使用内置的 nestjs 验证管道,这是我的引导程序:

async function bootstrap() {
  const app = await NestFactory.create(ServerModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(config.PORT);
}
bootstrap();

It's working fine for others properties, the array of object is the only one not working.

它对其他属性工作正常,对象数组是唯一一个不工作的。

回答by Kim Kern

You are expecting positions: [1]to throw a 400 but instead it is accepted.

您希望positions: [1]抛出 400,但它被接受了。

According to this Github issue, this seems to be a bug in class-validator. If you pass in a primitive type (boolean, string, number,...) or an arrayinstead of an object, it will accept the input as valid although it shouldn't.

根据这个Github 问题,这似乎是类验证器中的一个错误。如果您传入原始类型 ( boolean, string, number,...) 或一个array而不是对象,它会接受输入为有效,尽管它不应该。



I don't see any standard workaround besides creating a custom validation decorator:

除了创建自定义验证装饰器之外,我没有看到任何标准的解决方法:

import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';

export function IsNonPrimitiveArray(validationOptions?: ValidationOptions) {
  return (object: any, propertyName: string) => {
    registerDecorator({
      name: 'IsNonPrimitiveArray',
      target: object.constructor,
      propertyName,
      constraints: [],
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          return Array.isArray(value) && value.reduce((a, b) => a && typeof b === 'object' && !Array.isArray(b), true);
        },
      },
    });
  };
}

and then use it in your dto class:

然后在你的 dto 类中使用它:

@ValidateNested({ each: true })
@IsNonPrimitiveArray()
@Type(() => PositionDto)
positions: PositionDto[];