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

问题描述 投票:0回答:3

我正在尝试在 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);
    }
}

trivia.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
  }
]

此处的属性未得到验证。即使我在answer_in_time字段中传递一个字符串,它也会接受主体并且不会引发错误,或者如果我在任何字段中传递空字符串,那么它也会接受请求主体。

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

typescript validation nestjs dto class-validator
3个回答
3
投票

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

set

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

main.ts

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

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


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

为什么我们在使用class-transformer时不应该使用enableImplicitConversion?


2
投票

我也遇到过这样的问题,谷歌搜索后我发现使用

new ParseArrayPipe({items: YourDto, whitelist: true})

在控制器中。你也这样做了,你说 body 将是数组,但你的 dto 实际上不是数组

postTriviaScoreDto: PostTriviaScoreDto // --> mistake

如果你这样做了:

postTriviaScoreDto: PostTriviaScoreDto[] // this will solve your problem
 

信息取自此网站


0
投票

为了让其他人清楚,有效的答案是由 Kyung Lee 在其中一条评论中发布的,并且来自官方 NestJS 文档这里

特别需要实现的代码是 ParseArrayPipe,它指定位于 DTO 数组中的对象类型:

@Body(new ParseArrayPipe({ items: CreateUserDto }))
© www.soinside.com 2019 - 2024. All rights reserved.