如何使用 dto 验证 nestjs 中的对象数组

Posted

技术标签:

【中文标题】如何使用 dto 验证 nestjs 中的对象数组【英文标题】:How to validate an array of objects in nestjs using dto 【发布时间】:2021-08-10 08:32:49 【问题描述】:

我正在尝试使用 nestjs 中的 DTO 验证对象数组。我已经尝试过了,但数据没有得到验证。我试图搜索很多但没有得到任何答案。 这些是我的文件:

trivia.controller.ts 文件

import  Controller, Post, Body, ParseArrayPipe  from '@nestjs/common';
import  LoggerService  from '../logger/logger.service';
import  TriviaService  from './trivia.service';
import  PostTriviaScoreDto  from './dto/post-trivia-score.dto';

@Controller('trivia')
export class TriviaController 
  constructor(private readonly logger: LoggerService, private readonly triviaService: TriviaService) 

    @Post('score')
    postTriviaScore(@Body(new ParseArrayPipe( items: PostTriviaScoreDto )) postTriviaScoreDto: PostTriviaScoreDto) 
        this.logger.info('Trivia Controller : postTriviaScore : start');
        return this.triviaService.postTriviaScore(postTriviaScoreParamsDto, postTriviaScoreDto);
    

琐事.service.ts 文件

import  LoggerService  from '../logger/logger.service';
import  PostTriviaScoreDto  from './dto/post-trivia-score.dto';

 @Injectable()
export class TriviaService 
  constructor(
    private readonly logger: LoggerService,
  ) 
    postTriviaScore(allPlayersTriviaScore: PostTriviaScoreDto) 
            this.logger.info('Trivia Service : postTriviaScore : start');
            console.log('allPlayersScore ', allPlayersTriviaScore);
    
    

post-trivia-score.dto.ts 文件

import  Type  from 'class-transformer';
import  IsNotEmpty, IsUUID, ValidateNested  from 'class-validator';

class TriviaScore 
  @IsNotEmpty()
  @IsUUID()
  question_id: string;

  @IsNotEmpty()
  @IsUUID()
  selected_option_id: string;

  @IsNotEmpty()
  answered_in_time: number;


export class PostTriviaScoreDto 
  @ValidateNested( each: true )
  @Type(() => TriviaScore)
  items: TriviaScore[];

我的 JSON 结构

[
  
    "question_id": "088f1344-061e-4bcc-966f-512775f1f082",
    "selected_option_id": "72305e08-fedd-49b1-adb9-1dd92c88f4db",
    "answered_in_time": 2
  
]

此处未验证属性。即使我在 answers_in_time 字段中传递一个字符串,它也会接受正文并且不会抛出错误,或者如果我在任何字段中传递空字符串,它也会接受请求正文。

如果你们知道解决方案,请帮助我,因为我真的被困在这里了。

【问题讨论】:

【参考方案1】:

我认为那里的嵌套类没有初始化并且仅将其用于类型引用,因此类转换器不知道如何将其转换为类实例。

设置enableImplicitConversion: true可以请求class-transformer隐式转换

ma​​in.ts

import  ValidationPipe  from '@nestjs/common';
app.useGlobalPipes(
    new ValidationPipe(
      transformOptions: 
        enableImplicitConversion: true, // allow conversion underneath
      ,
    ),
);

之后,嵌套的属性应该能够被验证。


有些人说隐式转换在其他情况下可能有问题,但如果类没有实例化,我找不到干净的解决方案:

Why should we NOT use enableImplicitConversion when using class-transformer?

【讨论】:

以上是关于如何使用 dto 验证 nestjs 中的对象数组的主要内容,如果未能解决你的问题,请参考以下文章

自定义对象验证在 Nestjs DTO 中不起作用

NestJS:如何在@Query 对象中转换数组

如何在 NestJs 框架中使用 postgres 和 sequelize 正确定义 DTO 对象

在nestjs中使用类验证器验证环境变量?

Nestjs IsEnum dto 验证和招摇

NestJs:为啥我们不使用 DTO 来替换所有接口?