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

NestJS ValidationPipe配置@ValidateNested和@Type后不校验嵌套对象问题

问题原因

  1. ParentObject的Child属性缺少基础校验装饰器:class-validator默认会跳过没有任何基础校验装饰器的属性,仅配置@ValidateNested不足以触发嵌套校验逻辑。
  2. Nest默认的ValidationPipe返回的校验错误为嵌套结构,不会自动拼接父属性前缀生成Child.Data这类格式的扁平化错误消息,需要自定义异常工厂处理错误结构。

解决步骤

1. 修改父类定义,给嵌套属性新增基础校验装饰器

在parent-object.ts中给Child属性加上@IsObject()、@IsDefined()装饰器,确保嵌套属性会被识别为需要校验的字段:

import { Type } from 'class-transformer';
import { IsString, MinLength, ValidateNested, IsObject, IsDefined } from 'class-validator';

import { NestedObject } from './nested-object';

export class ParentObject {
    @IsString() @MinLength(1) public readonly FileName: string;

    @IsDefined() // 校验Child属性必须存在
    @IsObject() // 校验Child必须为对象类型
    @ValidateNested()
    @Type(() => NestedObject)
    public Child: NestedObject;
}

2. 调整ValidationPipe配置,新增自定义异常工厂

修改测试用例中ValidationPipe的初始化参数,新增exceptionFactory配置,把嵌套的错误消息打平为带父属性前缀的格式:

const target: ValidationPipe = new ValidationPipe({
    transform: true,
    whitelist: true,
    enableDebugMessages: true,
    errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
    // 自定义异常工厂,打平嵌套错误路径
    exceptionFactory: (errors) => {
        const buildMessages = (errors: any[], parentPath = '') => {
            let messages: string[] = [];
            errors.forEach(err => {
                const currentPath = parentPath ? `${parentPath}.${err.property}` : err.property;
                if (err.constraints) {
                    Object.values(err.constraints).forEach(msg => {
                        // 调整消息格式,匹配预期输出
                        const formatMsg = msg.replace(/^[A-Z]/, c => c.toLowerCase());
                        messages.push(`${currentPath} ${formatMsg}`);
                    });
                }
                if (err.children?.length) {
                    messages = messages.concat(buildMessages(err.children, currentPath));
                }
            });
            return messages;
        };
        return {
            statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
            message: buildMessages(errors),
            error: 'Unprocessable Entity'
        };
    }
});

修改完成后重新运行测试,即可返回预期的5条校验错误信息。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:39:00