【问题标题】:Pass @IsInt() validation for application/x-www-form-urlencoded request type通过 @IsInt() 验证 application/x-www-form-urlencoded 请求类型
【发布时间】:2018-08-05 07:28:15
【问题描述】:

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

我的请求数据如下所示

我的 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);
    }
}

当我调试这个管道时,我注意到了这个状态 其中:

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

如您所见,错误告诉我们年龄必须是整数

如何通过@IsInt() 验证application/x-www-form-urlencoded 请求?

库版本:

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

P.S:我还创建了一个repository,您可以在其中运行应用程序来测试错误。所需的分支 how-to-pass-int-validation

UPD:在对接受的答案进行更改后,我遇到了将错误的解析数据存储到存储中的问题。 Recorded example

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

【问题讨论】:

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


    【解决方案1】:

    来自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;
    }
    

    【讨论】:

    • 只有一个问题:Number.isNan() 不存在。我们需要使用isNaN() 来代替它。
    • 还有一个问题:通过验证后,我得到了字符串的值(我对我的问题进行了更新)。将正确数据传递给控制器​​的正确方法是什么?
    • 根据您的验证管道,您需要返回object 变量,而不是value 变量。
    • 这是全局管道更改的正确行为吗?我基于docs 编写了该代码,只是想知道返回object 而不是value 会很方便
    • 我在项目中使用object
    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 2021-06-19
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    相关资源
    最近更新 更多