Class 转换器未转换为数字数组
Class transformer not converting to array of numbers
我有一个 DTO,其中有一个字段,它是一个数字数组。这些 ID 来自 API 查询参数。我正在使用 Class Transformer 将这些 id 转换为数字数组。但我只得到一个字符串数组。我的 DTO class 如下。
export class EvseGetQueryDto {
...
...
@IsOptional()
@IsArray()
@IsNumber({}, {each: true})
@ApiProperty({ type: [Number] })
@Type(() => Number)
locations?: number[];
...
...
}
我的控制器代码如下所示。
async GetAll(@Query() query: EvseGetQueryDto): Promise<EvseDto[]> {
return await this.evseService.GetAll(query);
}
如果我像下面这样调用我的控制器,我仍然会在我的位置字段中得到 ['1', '2']
。
http://localhost:3000/evses?locations[]=1&locations[]=2
有人可以指导我吗?
查询参数始终以字符串形式出现,如果您使用 URL 参数,也是如此。 @Type(() => Number)
足以修改它,但您需要确保在 ValidationPipe
.
中设置了 transform: true
import { Type } from 'class-transformer';
import { IsArray, IsNumber } from 'class-validator';
export class NumbersQuery {
@Type(() => Number)
@IsArray()
@IsNumber({}, {each: true})
numbers: number[];
}
import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common';
import { AppService } from './app.service';
import { NumbersQuery } from './numbers';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(@Query() query: Record<string, unknown>): string {
return this.appService.getHello(query);
}
@UsePipes(new ValidationPipe({ transform: true }))
@Get('numbers')
getNumbers(@Query() numbers: NumbersQuery) {
console.log(numbers);
return numbers.numbers;
}
}
▶ curl http://localhost:3000/numbers/\?numbers\[\]\=1\&numbers\[\]\=2
[1,2]%
[Nest] 76497 - 10/23/2020, 10:40:47 AM [NestFactory] Starting Nest application...
[Nest] 76497 - 10/23/2020, 10:40:47 AM [InstanceLoader] AppModule dependencies initialized +11ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [RoutesResolver] AppController {}: +5ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [RouterExplorer] Mapped {, GET} route +2ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [RouterExplorer] Mapped {/numbers, GET} route +1ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [NestApplication] Nest application successfully started +1ms
NumbersQuery { numbers: [ 1, 2 ] }
我有一个 DTO,其中有一个字段,它是一个数字数组。这些 ID 来自 API 查询参数。我正在使用 Class Transformer 将这些 id 转换为数字数组。但我只得到一个字符串数组。我的 DTO class 如下。
export class EvseGetQueryDto {
...
...
@IsOptional()
@IsArray()
@IsNumber({}, {each: true})
@ApiProperty({ type: [Number] })
@Type(() => Number)
locations?: number[];
...
...
}
我的控制器代码如下所示。
async GetAll(@Query() query: EvseGetQueryDto): Promise<EvseDto[]> {
return await this.evseService.GetAll(query);
}
如果我像下面这样调用我的控制器,我仍然会在我的位置字段中得到 ['1', '2']
。
http://localhost:3000/evses?locations[]=1&locations[]=2
有人可以指导我吗?
查询参数始终以字符串形式出现,如果您使用 URL 参数,也是如此。 @Type(() => Number)
足以修改它,但您需要确保在 ValidationPipe
.
transform: true
import { Type } from 'class-transformer';
import { IsArray, IsNumber } from 'class-validator';
export class NumbersQuery {
@Type(() => Number)
@IsArray()
@IsNumber({}, {each: true})
numbers: number[];
}
import { Controller, Get, Query, UsePipes, ValidationPipe } from '@nestjs/common';
import { AppService } from './app.service';
import { NumbersQuery } from './numbers';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(@Query() query: Record<string, unknown>): string {
return this.appService.getHello(query);
}
@UsePipes(new ValidationPipe({ transform: true }))
@Get('numbers')
getNumbers(@Query() numbers: NumbersQuery) {
console.log(numbers);
return numbers.numbers;
}
}
▶ curl http://localhost:3000/numbers/\?numbers\[\]\=1\&numbers\[\]\=2
[1,2]%
[Nest] 76497 - 10/23/2020, 10:40:47 AM [NestFactory] Starting Nest application...
[Nest] 76497 - 10/23/2020, 10:40:47 AM [InstanceLoader] AppModule dependencies initialized +11ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [RoutesResolver] AppController {}: +5ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [RouterExplorer] Mapped {, GET} route +2ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [RouterExplorer] Mapped {/numbers, GET} route +1ms
[Nest] 76497 - 10/23/2020, 10:40:47 AM [NestApplication] Nest application successfully started +1ms
NumbersQuery { numbers: [ 1, 2 ] }