使用nest.js控制器中的class-validator验证嵌套对象 [英] validate nested objects using class-validator in nest.js controller

查看:207
本文介绍了使用nest.js控制器中的class-validator验证嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在nest.js控制器中使用类验证器来验证主体有效载荷.我的currency.dto.ts文件是这样的:

I want to validate body payload using class-validator in a nest.js controller. My currency.dto.ts file is like this:

import {
  IsNotEmpty,
  IsString,
  ValidateNested,
  IsNumber,
  IsDefined,
} from 'class-validator';

class Data {

  @IsNotEmpty()
  @IsString()
  type: string;

  @IsNotEmpty()
  @IsNumber()
  id: number;
}

export class CurrencyDTO {
  @ValidateNested({ each: true })
  @IsDefined()
  data: Data[];
}

在我的nest.js控制器中,我像这样使用它.

and in my nest.js controller, I use it like this.

  @Post()
  @UseGuards(new AuthTokenGuard())
  @UsePipes(new ValidationPipe())
  addNewCurrency(@Req() req, @Body() data: CurrencyDTO) {
    console.log('data', data);
  }

我的验证管道类是这样的:

my validation pipe class is like this:

import {
  PipeTransform,
  Injectable,
  ArgumentMetadata,
  BadRequestException,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { validate, IsInstance } from 'class-validator';
import { plainToClass, Exclude } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, metadata: ArgumentMetadata) {
    if (value instanceof Object && this.isEmpty(value)) {
      throw new HttpException(
        `Validation failed: No Body provided`,
        HttpStatus.BAD_REQUEST,
      );
    }
    const { metatype } = metadata;
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errorsList = await validate(object);
    if (errorsList.length > 0) {
      const errors = [];
      for (const error of errorsList) {
        const errorsObject = error.constraints;
        const { isNotEmpty } = errorsObject;
        if (isNotEmpty) {
          const parameter = isNotEmpty.split(' ')[0];
          errors.push({
            title: `The ${parameter} parameter is required.`,
            parameter: `${parameter}`,
          });
        }
      }
      if (errors.length > 0) {
        throw new HttpException({ errors }, HttpStatus.BAD_REQUEST);
      }
    }
    return value;
  }

  private toValidate(metatype): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return !types.find(type => metatype === type);
  }
  private isEmpty(value: any) {
    if (Object.keys(value).length > 0) {
      return false;
    }
    return true;
  }
}

此验证管道对除嵌套对象以外的所有对象均适用.知道我在做什么错吗? 我的身体有效载荷是这样的:

This validation pipe works fine for all except for nested objects. Any idea what am I doing wrong here? My body payload is like this:

{
"data": [{
    "id": 1,
    "type": "a"
}]
}

推荐答案

尝试使用@Type指定嵌套类型:

Try specifying the nested type with @Type:

import { Type } from 'class-transformer';

export class CurrencyDTO {
  @ValidateNested({ each: true })
  @Type(() => Data)
  data: Data[];
}

对于要验证的嵌套类型,它必须是类的实例,而不仅仅是普通数据对象.使用@Type装饰器,您可以告诉class-transformer在VaildationPipe中调用plainToClass时为给定属性实例化一个类.

For a nested type to be validated, it needs to be an instance of a class not just a plain data object. With the @Type decorator you tell class-transformer to instantiate a class for the given property when plainToClass is called in your VaildationPipe.

如果您使用内置的ValidationPipe,请确保已设置选项transform: true.

If you are using the built-in ValidationPipe make sure you have set the option transform: true.

这篇关于使用nest.js控制器中的class-validator验证嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆