nestjs - @Query() 不会转换为 DTO
问题描述
我有一个控制器需要接收请求查询字符串中的数据(我不能使用正文,因为我正在与遗留系统交互)。
我将 DTO 映射查询参数写入对象,并使用 ValidationPipe 验证数据并将其转换为我的 DTO。
所以,我有这个:
import { Get, Controller, Query, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
class TestDto {
@IsNumber()
field1: number;
@IsBoolean()
field2: boolean;
}
@Controller()
export class AppController {
constructor() {}
@Get()
@UsePipes(new ValidationPipe({ whitelist: false, transform: true}))
root(@Query() dto: TestDto): TestDto {
return dto;
}
}
前面的所有代码都编译并遵循 NestJS 文档,但是当我调用http://localhost:3000/?field1=15&field2=true时,我得到了这个:
{
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"target": {
"field1": "15",
"field2": "true"
},
"value": "15",
"property": "field1",
"children": [],
"constraints": {
"isNumber": "field1 must be a number"
}
},
{
"target": {
"field1": "15",
"field2": "true"
},
"value": "true",
"property": "field2",
"children": [],
"constraints": {
"isBoolean": "field2 must be a boolean value"
}
}
]
}
根据属性,这两个字段都有效,但管道拒绝请求。如果我从 @IsNumber 更改为 @IsNumberString 并从 @IsBoolean 更改为 @IsBooleanString 它会验证,但我没有收到转换后的数据(即我得到一个普通对象而不是我的 DTO)
有人遇到过这样的事情吗?
解决方案
它不能,因为接口只能塑造你的结构或告诉一些关于类型的东西。由于同样的事实,您的验证将无法正常工作。
class TestDto
请参阅 NestJS 文档 - 自动验证 NestJS 文档 - 有效负载转换
正如文档中的示例所说:
import { IsEmail, IsNotEmpty } from 'class-validator'; // 'class'
export class CreateUserDto { // notice class
@IsEmail()
email: string;
@IsNotEmpty()
password: string;
}
更新 #1 - 告诉验证器尝试进行隐式转换
@UsePipes( new ValidationPipe( { transform: true, transformOptions: {enableImplicitConversion: true} }))
更新 #2 - 使用自定义@Query()
参数装饰器
import { Controller, createParamDecorator, Get, UsePipes, ValidationPipe } from '@nestjs/common';
import { IsNumber } from 'class-validator';
import { AppService } from './app.service';
const MyField = createParamDecorator((data, req) => {
const result = new TestDto();
result.field1 = Number(req.query.field1);
return result;
});
class TestDto {
@IsNumber()
field1: number;
}
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {
}
@Get()
@UsePipes(new ValidationPipe({ transform: true }))
getHello(@MyField() testDto: TestDto): TestDto {
return testDto;
}
}
推荐阅读
- c# - 如何检查http链接中是否有错误,然后继续?
- database - iMessages chat.db 的 sqlite3 日期转换
- c - 内存访问的分段错误
- mysql - 即使存在使用键列的 where 子句,删除也会失败
- apache-spark - 加入火花时如何处理这个模糊的错误?
- javascript - 如何使用 jest 在 reducer 中模拟一个函数
- bash - 从 yaml 文件中的变量中提取 yaml 文件
- python - 使用 Python 中的文件通过动态嵌套字典构建图形
- sql - 当我必须测试多个表时如何形成子查询?
- android - android.view.InflateException: Binary XML file line #14: Error inflating class android.widget.GridView