NestJS的ValidationPipe在@Query()中无法正常工作

3

我正在尝试使用内置的NestJS ValidationPipe将一些查询参数从字符串转换为整数,但似乎它并没有正常工作。

这是我的控制器:

import {
..., ValidationPipe
} from '@nestjs/common';

...

@UseGuards(JwtAuthGuard)
@Get()
findAll(@Req() req, @Query(new ValidationPipe({
    transform: true,
    transformOptions: { enableImplicitConversion: true },
    forbidNonWhitelisted: true,
})) query: GetTestDto) {
    return this.testService.findAll(query, req.user.id);
}

这是我的数据传输对象(DTO):

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

export class GetTestDto {
    @IsOptional()
    @IsString()
    public search: string;

    @IsOptional()
    @Transform(({value}) => {
        console.log(typeof value); // => string / I'm just testing here
        return value
    })
    @IsInt()
    public page: number;

    @IsOptional()
    @IsInt()
    public limit: number;
}

main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import cookieParser from 'cookie-parser';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.setGlobalPrefix('api');
    app.use(cookieParser());
    app.useGlobalPipes(new ValidationPipe());
    await app.listen(3000);
}

bootstrap();

当我尝试调用GET http://127.0.0.1:3000/api/test?page=1&limit=10时,我会得到这个结果。
validation error from the DTO I think:
{
    "statusCode": 400,
    "message": [
        "page must be an integer number",
        "limit must be an integer number"
    ],
    "error": "Bad Request"
} 

我已经尝试删除node_modules和dist文件夹,但是没有什么改变。 我不想在数据传输对象(DTO)中使用@Transform()作为解决方案,我更希望管道(pipeline)通过 enableImplicitConversion: true 来完成转换。

能否请您给我提供一些帮助?

谢谢!

2个回答

6
  • main.ts文件中传递ValidationPipe选项
app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
      transformOptions: {
        enableImplicitConversion: true,
      },
      whitelist: true,
    })
  );
  1. 在您的DTO类中删除@Transform装饰器。

  2. 在您的控制器中,删除传递给@Query装饰器的ValidationPipe。

@UseGuards(JwtAuthGuard)
@Get()
findAll(@Req() req, @Query() query: GetTestDto) {
    return this.testService.findAll(query, req.user.id);
}

是的,我遇到的错误来自于全局验证管道,在其中我没有启用转换和隐式转换。 - RustyJoe

-1

查询(@Query())和 URL(@Param())参数始终以字符串形式出现。为了强制将它们解析为数字,您可以添加 @Type(() => Number),这样 class-transformer 就会将它们转换为数字,然后 class-validator 读取正确的值。


如果我使用@Type(() => Number)的方法,那么在@Query()中就不需要ValidationPipe(){ enableImplicitConversion: true }了,对吧?我想让内置的NestJS ValidationPipe来为我设置转换,而不是在DTO中显式地设置转换。顺便说一下,我正在遵循这个人的答案:链接 - RustyJoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接