使用“excludeExtraneousValues”NestJS 标志不起作用

Roy*_*itz 4 dto class-validator nestjs

我在 NestJS 中有一个用户的 DTO 类。我正在使用类验证器包进行许多验证,以强制执行我的逻辑。如果 DTO 定义中不存在某个字段,我想忽略它,甚至抛出错误。这就是我尝试使用“excludeExtraneousValues”标志的原因。当我使用它时,它会忽略所有字段,甚至是 DTO 中定义的字段。

import { ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsDefined,
  IsEmail,
  IsOptional,
  IsPhoneNumber,
  MaxLength,
  ValidateIf,
} from 'class-validator';

export default class UserDTO {
  
  @ApiPropertyOptional()
  @MaxLength(254)
  @IsEmail()
  @IsDefined()
  @ValidateIf((object) => object.email || !object.phone_number)
  email?: string;

  @ApiPropertyOptional()
  @MaxLength(15)
  @IsPhoneNumber()
  @IsDefined()
  @ValidateIf((object) => object.phone_number || !object.email)
  phone_number?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @MaxLength(40)
  name?: string;
}
Run Code Online (Sandbox Code Playgroud)

正如我提到的,我正在使用 NestJS。这是 ValidationPipe 定义:

  app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
      stopAtFirstError: true,
      transformOptions: { excludeExtraneousValues: true },
    }),
  );
Run Code Online (Sandbox Code Playgroud)

添加“excludeExtraneousValues”标志后,我无法发送任何值,即使是定义的值。

这是一个错误还是我错过了什么?

fir*_*orx 9

有点旧,但我偶然发现它被投票了,所以这里是:

我想知道您是否混淆了输入与输出。你的问题不够具体,我无法百分百确定。NestJS 应用程序通常在等式两端使用类验证器和类转换器库,并且可以在使用这些库中的装饰器装饰的 DTO/实体上工作。

像您这样的管道ValidationPipe适用于事物的输入端。请参阅文档: https: //docs.nestjs.com/techniques/validation

通常class-validator是输入端的关键角色,class-transformer仅在适用的装饰器(例如@Transform(). 要使用类转换器,您需要transform: true像以前一样传递选项。

如果您想控制有关进入您的ValidationPipe实体/DTO 类中未定义的数据字段的行为,请查看whitelist: booleanforbidNonWhitelisted: booleanforbidUnknownValues: true配置选项以满足您在输入方面的需求。

我有一种感觉,一旦你检查了这些选项,你会发现你会想要删除该transformOptions: { excludeExtraneousValues: true }选项。

在输出方面,拦截器发挥作用。通常在 NestJS 项目中,包含的内容ClassSerializerInterceptor用于将 DTO/实体类的实例序列化为 JSON 以进行响应。文档: https: //docs.nestjs.com/techniques/serialization

在这一面,您会看到更频繁地使用类转换器的装饰器,例如Exclude()Expose()Transform()

这也是您更有可能找到配置选项(如excludeExtraneousValues.

假设您在一个对象中有数据(例如来自数据库、文件或任何地方)并且想要填充一个类(例如 DTO),以便您可以利用这些装饰器,但只想将某些字段实际发送回响应,即您在类中明确指定和装饰的响应,并且您不想在各处使用Exclude()和装饰器。Expose()

在这种情况下,类转换器的选项可能会派上用场,具体取决于您想要做什么,例如

app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector), { excludeExtraneousValues: true }))
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用。谢谢 `app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector), { exclueExtraneousValues: true }))` (2认同)