通过@IsInt()验证application / x-www-form-urlencoded请求类型

时间:2018-02-25 20:55:25

标签: node.js nestjs class-validator class-transformer

当我浏览 Pipes 文档时,我注意到我无法正确地对 application / x-www-form-urlencoded 请求进行@IsInt()验证,导致我传递的所有值都是字符串值。

我的请求数据如下所示 enter image description here

我的DTO看起来像

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
    @IsString()
    readonly name: string;

    @IsInt()
    readonly age: number;

    @IsString()
    readonly breed: string;
}

验证管道包含下一个代码

import { PipeTransform, Pipe, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Pipe()
export class ValidationPipe implements PipeTransform<any> {
    async transform(value, metadata: ArgumentMetadata) {
        const { metatype } = metadata;
        if (!metatype || !this.toValidate(metatype)) {
            return value;
        }
        const object = plainToClass(metatype, value);
        const errors = await validate(object);
        if (errors.length > 0) {
            throw new BadRequestException('Validation failed');
        }
        return value;
    }

    private toValidate(metatype): boolean {
        const types = [String, Boolean, Number, Array, Object];
        return !types.find((type) => metatype === type);
    }
}

当我调试这个管道时,我注意到了这个状态 enter image description here 地点:

  • - 请求正文值
  • 对象 - 通过 class-transformer
  • 进行转换
  • 错误 - 错误对象

正如您所看到的,错误告诉我们年龄必须是整数

如何为 application / x-www-form-urlencoded 请求传递@IsInt()验证?

图书馆版本:

  • @ nestjs / common @ 4.6.4
  • class-transformer@0.1.8
  • class-validator@0.8.1

P.S:我还创建了一个repository,您可以在其中运行应用程序来测试错误。必需分支如何通过验证

UPD :从接受的答案进行更改后,我面临的问题是我将错误的已解析数据存储到存储中。 Recorded example

是否可以很好地解析createCatDto或我需要做什么来保存正确的类型结构?

1 个答案:

答案 0 :(得分:2)

application/x-www-form-urlencoded请求中的所有值都是字符串。

所以,您可以执行以下操作:

import { Transform } from 'class-transformer';
import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  readonly name: string;

  @Transform(value => Number.isNan(+value) ? 0 : +value) // this field will be parsed to integer when `plainToClass gets called`
  @IsInt()
  readonly age: number;

  @IsString()
  readonly breed: string;
}