You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS DTO校验:如何确保请求至少传入一个属性?

解决DTO空对象校验问题

要实现“请求至少传入一个属性”的校验,你可以通过自定义class-validator校验器来实现,具体步骤如下:

1. 创建自定义校验器

定义一个校验器类,用于检查DTO实例是否至少包含一个非未定义的属性:

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';

@ValidatorConstraint({ name: 'atLeastOneField', async: false })
export class AtLeastOneFieldValidator implements ValidatorConstraintInterface {
  validate(obj: Record<string, any>, args: ValidationArguments) {
    // 遍历对象属性,判断是否存在至少一个非undefined的属性
    return Object.values(obj).some(value => value !== undefined);
  }

  defaultMessage(args: ValidationArguments) {
    return '请求体至少需要传入一个有效属性';
  }
}

2. 在DTO类上应用校验器

修改你的WorkspaceDto,在类级别添加@Validate装饰器引入自定义校验器:

// import libs
import { Validate } from 'class-validator';
import { AtLeastOneFieldValidator } from './path-to-your-validator'; // 替换为实际文件路径

export class WorkspaceDto {
  @Validate(AtLeastOneFieldValidator) // 类级别校验,强制至少传一个属性
  @IsString()
  @IsNotEmpty()
  @Transform(({ value }) => value?.trim())
  @ApiProperty()
  @IsOptional()
  id?: string;

  @IsString()
  @IsNotEmpty()
  @Transform(({ value }) => value?.trim())
  @ApiProperty()
  @IsOptional()
  name?: string;

  @IsNotEmpty()
  @IsString()
  @Transform(({ value }) => value?.trim())
  @ApiProperty()
  @IsOptional()
  domain?: string;

  @IsNotEmpty()
  @IsString()
  @Transform(({ value }) => value?.trim())
  @IsOptional()
  @ApiProperty({ enum: WorkspaceStatusEnum, required: false })
  @IsEnum(WorkspaceStatusEnum)
  status?: WorkspaceStatusEnum;
}

逻辑说明

  • 保留每个字段的@IsOptional,允许单个字段可选,但类级别校验会强制要求至少有一个字段被传入。
  • 当用户传入空对象{}时,自定义校验器会返回false,触发错误提示拦截请求。
  • 单个字段的@IsNotEmpty等校验依然生效,确保传入的字段值符合格式要求。

内容的提问来源于stack exchange,提问作者green_dino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:34:52