Nestjs ValidationPipe({transform: true}) 不会将请求正文的字符串转换为数字

Dan*_*ikh 6 dto class-validator nestjs class-transformer

正如文档中提到的

ValidationPipe 可以自动将有效负载转换为根据其 DTO 类键入的对象。要启用自动转换,请将转换设置为 true。

但我总是收到错误请求,因此转换不起作用。

邮递员请求体

验证DTO

export class CreateDistrictDto {
    @IsString()
    @IsNotEmpty()
    name: string;
    
    
    // associations
    @IsNotEmpty()
    @IsNumber()
    cityId: number;
}
Run Code Online (Sandbox Code Playgroud)

控制器中的路线

    @Post()
    async createCity(@Body() cityDto: CreateCityDto) {
        return await this.cityService.createCity(cityDto);
    }
Run Code Online (Sandbox Code Playgroud)

main.ts(我使用默认的@nestjs/common ValidationPipe)

app.useGlobalPipes(new ValidationPipe({
    transform: true,
}));
Run Code Online (Sandbox Code Playgroud)

这个答案说转换不适用于基元,这似乎是正确的。

/sf/answers/4702707831/ https://github.com/nestjs/nest/blob/master/packages/common/pipes/validation.pipe.ts#L137

那么为什么文档另有说法,transform: true 选项的用途是什么?

Jay*_*iel 17

所以看起来并body-parser没有将数字隐式转换为数字。要解决此问题,请发送application/json带有显式数字的 JSON 请求 ( ),或者class-transformer通过transformOptions: { enableImplicitConversion: true },in the ValidationPipeoptions 在选项中启用隐式类型转换。

{
  provide: APP_PIPE,
  useValue: new ValidationPipe({
    transform: true,
    transformOptions: { enableImplicitConversion: true },
  }),
},
Run Code Online (Sandbox Code Playgroud)

  • 冒着激起 stackoverflow 诸神的愤怒的风险……谢谢!节省了我很多时间 - 希望我早点找到这个 (3认同)

mos*_*lem 5

@Transform()要转换您需要使用模块的值class-transform,例如:

import { Transform } from 'class-transformer';
import { IsNumber } from 'class-validator';

export class CreateProductDto {
  @IsNumber()
  @Transform(({ value }) => {
    return Number(value);
  })
  pieces: number;
}
Run Code Online (Sandbox Code Playgroud)