使用类验证器和nestjs

时间:2018-12-14 20:17:51

标签: javascript node.js typescript nestjs class-validator

我正在尝试使用class-validator和NestJS来验证嵌套对象。我已经尝试通过使用class-transform的@Type装饰器来遵循此thread,但没有任何运气。这就是我所拥有的:

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[];

}

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

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

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

2 个答案:

答案 0 :(得分:5)

您期望positions: [1]掷出400,但可以接受。

根据此Github issue,这似乎是类验证器中的错误。如果您传入原始类型(booleanstringnumber,...)或array而不是对象,则尽管输入有效,但不应该。


除了创建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);
        },
      },
    });
  };
}

,然后在您的dto类中使用它:

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

答案 1 :(得分:3)

对我来说,我可以使用'class-transformer'

来验证嵌套对象
import { Type } from 'class-transformer';

完整示例:

import {
  MinLength,
  MaxLength,
  IsNotEmpty,
  ValidateNested,
  IsDefined,
  IsNotEmptyObject,
  IsObject,
  IsString,
} from 'class-validator';
import { Type } from 'class-transformer';

class MultiLanguageDTO {
  @IsString()
  @IsNotEmpty()
  @MinLength(4)
  @MaxLength(40)
  en: string;

  @IsString()
  @IsNotEmpty()
  @MinLength(4)
  @MaxLength(40)
  ar: string;
}

export class VideoDTO {
  @IsDefined()
  @IsNotEmptyObject()
  @IsObject()
  @ValidateNested()
  @Type(() => MultiLanguageDTO)
  name!: MultiLanguageDTO;
}