@Query()不会转换为DTO

时间:2019-10-14 13:04:28

标签: nestjs

我有一个控制器,该控制器需要接收请求查询字符串中的数据(由于要与旧版系统进行交互,因此无法使用主体)。

我编写了一个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)

有人面对这样的事情吗?

2 个答案:

答案 0 :(得分:1)

它不能,因为接口只会影响您的结构或告诉您有关类型的信息。由于相同的事实,您的验证将无法正常工作。

class TestDto

请参阅 NestJS docs - Auto Validation NestJS docs - Payload transforming

以文档中的示例为例:

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

答案 1 :(得分:1)

您也可以在main.ts上使用app.useGlobalPipes(new ValidationPipe({ transform: true }));。对我来说?